tags:

views:

2222

answers:

14

I get asked this question a lot and I thought I'd solicit some input on how to best describe the difference.

A: 

Well, the really oversimplified version is that a lambda is just shorthand for an anonymous function. A delegate can do a lot more than just anonymous functions: things like events, asynchronous calls, and multiple method chains.

Joel Coehoorn
lambdas can be used as event handlers; button.Click += (sender, eventArgs) => { MessageBox.Show("Click"); }and called asynchronously new System.Threading.Thread(() => Console.Write("Executed on a thread")).Start();
Steve Cooper
+3  A: 

I don't have a ton of experience with this, but the way I would describe it is that a delegate is a wrapper around any function, whereas a lambda expression is itself an anonymous function.

chessguy
+5  A: 

Delegates are equivalent to function pointers/method pointers/callbacks (take your pick), and lambdas are pretty much simplified anonymous functions. At least that's what I tell people.

Dan Shield
Exactly! There is no "difference". They are two inherently different things.
ionut bizau
+2  A: 

lambdas are simply syntactic sugar on a delegate. The compiler ends up converting lambdas into delegates.

These are the same, I believe:

Delegate delegate = x => "hi!";
Delegate delegate = delegate(object x) { return "hi";};
Gilligan
neither of these examples compile. Even if you change the name of the instance of `Delegate` from 'delegate', which is a keyword.
Steve Cooper
+2  A: 

A delegate is a function signature; something like

delegate string MyDelegate(int param1);

The delegate does not implement a body.

The lambda is a function call that matches the signature of the delegate. For the above delegate, you might use any of;

(int i) => i.ToString();
(int i) => "ignored i";
(int i) => "Step " + i.ToString() + " of 10";

The Delegate type is badly named, though; creating an object of type Delegate actually creates a variable which can hold functions -- be they lambdas, static methods, or class methods.

Steve Cooper
When you create a variable of type MyDelegate, that isn't really it's runtime type. The runtime type is Delegate. There's compiler tricks involved in how delegates, lambdas, and expression trees compile, which I think cause the code imply things that aren't true.
Chris Ammerman
+3  A: 

A delegate is always just basically a function pointer. A lambda can turn into a delegate, but it can also turn into a LINQ expression tree. For instance,

Func<int, int> f = x => x + 1;
Expression<Func<int, int>> exprTree = x => x + 1;

The first line produces a delegate, while the second produces an expression tree.

Curt Hagenlocher
That is true, but the *difference* between them is that *they are two completely different concepts*. This is like comparing apples and oranges. See Dan Shield's answer.
ionut bizau
+1  A: 

Delegates are really just structural typing for functions. You could do the same thing with nominal typing and implementing an anonymous class that implements an interface or abstract class, but that ends up being a lot of code when only one function is needed.

Lambda comes from the idea of lambda calculus of Alonzo Church in the 1930s. It is an anonymous way of creating functions. They become especially useful for composing functions

So while some might say lambda is syntactic sugar for delegates, I would says delegates are a bridge for easing people into lambdas in c#.

Steve g
A: 

Lambdas are simplified versions of delegates. They have some of the the properties of a closure like anonymous delegates, but also allow you to use implied typing. A lambda like this:

something.Sort((x, y) => return x.CompareTo(y));

is a lot more concise than what you can do with a delegate:

something.Sort(sortMethod);
...

private int sortMethod(SomeType one, SomeType two)
{
    one.CompareTo(two)
}
Michael Meadows
You mean lambdas are like simplified anonymous methods (not delegate). Like methods (anonymous or not), they can be assigned to a delegate variable.
Lucas
+7  A: 

One difference is that an anonymous delegate can omit parameters while a lambda must match the exact signature. Given:

public delegate string TestDelegate(int i);

public void test(TestDelegate d)
{}

you can call it in the following four ways (note that the second line has an anonymous delegate that does not have any parameters):

test(delegate(int i) {return String.Empty;}
test(delegate{ return String.Empty; });
test(i => String.Empty);
test(D);

private string D(int i)
    {
        return String.Empty;
    }

You cannot pass in a lambda expression that has no parameters or a method that has no parameters. These are not allowed:

test(() => String.Empty); //Not allowed, lambda must match signature
test(D2); //Not allowed, method must match signature

private string D2()
    {
        return String.Empty;
    }
Karg
+22  A: 

They are actually two very different things. "Delegate" is actually the name for a variable that holds a reference to a method or a lambda, and a lambda is a method without a permanent name.

Lambdas are very much like other methods, except for a couple subtle differences.

  1. A normal method is defined in a "statement" and tied to a permanent name, whereas a lambda is defined "on the fly" in an "expression" and has no permanent name.
  2. Some lambdas can be used with .NET expression trees, whereas methods cannot.

A delegate is defined like this:

delegate Int32 BinaryIntOp(Int32 x, Int32 y);

A variable of type BinaryIntOp can have either a method or a labmda assigned to it, as long as the signature is the same: two Int32 arguments, and an Int32 return.

A lambda might be defined like this:

BinaryIntOp sumOfSquares = (a, b) => a*a + b*b;

Another thing to note is that although the generic Func and Action types are often considered "lambda types", they are just like any other delegates. The nice thing about them is that they essentially define a name for any type of delegate you might need (up to 4 parameters, though you can certainly add more of your own). So if you are using a wide variety of delegate types, but none more than once, you can avoid cluttering your code with delegate declarations by using Func and Action.

Here is an illustration of how Func and Action are "not just for lambdas":

Int32 DiffOfSquares(Int32 x, Int32 y)
{
  return x*x - y*y;
}

Func<Int32, Int32, Int32> funcPtr = DiffOfSquares;

Another useful thing to know is that delegate types (not methods themselves) with the same signature but different names will not be implicitly casted to each other. This includes the Func and Action delegates. However if the signature is identical, you can explicitly cast between them.

Going the extra mile.... In C# functions are flexible, with the use of lambdas and delegates. But C# does not have "first-class functions". You can use a function's name assigned to a delegate variable to essentially create an object representing that function. But it's really a compiler trick. If you start a statement by writing the function name followed by a dot (i.e. try to do member access on the function itself) you'll find there are no members there to reference. Not even the ones from Object. This prevents the programmer from doing useful (and potentially dangerous of course) things such as adding extension methods that can be called on any function. The best you can do is extend the Delegate class itself, which is surely also useful, but not quite as much.

Update: Also see Karg's answer illustrating the difference between anonymous delegates vs. methods & lambdas.

Update 2: James Hart makes an important, though very technical, note that lambdas and delegates are not .NET entities (i.e. the CLR has no concept of a delegate or lambda), but rather they are framework and language constructs.

Chris Ammerman
Good explanation. Although I think you mean "first-class functions", not "first-class objects". :)
ionut bizau
You're right. I had the sentence structured different during writing ("C# functions are not actually first-class objects") and forgot to change that. Thanks!
Chris Ammerman
A: 

Heres an example I put up awhile on my lame blog. Say you wanted to update a label from a worker thread. I've got 4 examples of how to update that label from 1 to 50 using delegates, anon delegates and 2 types of lambdas.

 private void button2_Click(object sender, EventArgs e) 
     { 
         BackgroundWorker worker = new BackgroundWorker(); 
         worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
         worker.RunWorkerAsync(); 
     } 

     private delegate void UpdateProgDelegate(int count); 
     private void UpdateText(int count) 
     { 
         if (this.lblTest.InvokeRequired) 
         { 
             UpdateProgDelegate updateCallBack = new UpdateProgDelegate(UpdateText); 
             this.Invoke(updateCallBack, new object[] { count }); 
         } 
         else 
         { 
             lblTest.Text = count.ToString(); 
         } 
     } 

     void worker_DoWork(object sender, DoWorkEventArgs e) 
     {   
         /* Old Skool delegate usage.  See above for delegate and method definitions */ 
         for (int i = 0; i < 50; i++) 
         { 
             UpdateText(i); 
             Thread.Sleep(50); 
         } 

         // Anonymous Method 
         for (int i = 0; i < 50; i++) 
         { 
             lblTest.Invoke((MethodInvoker)(delegate() 
             { 
                 lblTest.Text = i.ToString(); 
             })); 
             Thread.Sleep(50); 
         } 

         /* Lambda using the new Func delegate. This lets us take in an int and 
          * return a string.  The last parameter is the return type. so 
          * So Func<int, string, double> would take in an int and a string 
          * and return a double.  count is our int parameter.*/ 
         Func<int, string> UpdateProgress = (count) => lblTest.Text = count.ToString(); 
         for (int i = 0; i < 50; i++) 
         { 
             lblTest.Invoke(UpdateProgress, i); 
             Thread.Sleep(50); 
         } 

         /* Finally we have a totally inline Lambda using the Action delegate 
          * Action is more or less the same as Func but it returns void. We could 
          * use it with parameters if we wanted to like this: 
          * Action<string> UpdateProgress = (count) => lblT…*/ 
         for (int i = 0; i < 50; i++) 
         { 
             lblTest.Invoke((Action)(() => lblTest.Text = i.ToString())); 
             Thread.Sleep(50); 
         } 
     }
Echostorm
+1  A: 

A delegate is a reference to a method with a particular parameter list and return type. It may or may not include an object.

A lambda-expression is a form of anonymous function.

Peter Ritchie
+1  A: 

A delegate is a Queue of function pointers, invoking a delegate may invoke multiple methods. A lambda is essentially an anonymous method declaration which may be interpreted by the compiler differently, depending on what context it is used as.

You can get a delegate that points to the lambda expression as a method by casting it into a delegate, or if passing it in as a parameter to a method that expects a specific delegate type the compiler will cast it for you. Using it inside of a LINQ statement, the lambda will be translated by the compiler into an expression tree instead of simply a delegate.

The difference really is that a lambda is a terse way to define a method inside of another expression, while a delegate is an actual object type.

justin.m.chase
+9  A: 

The question is a little ambiguous, which explains the wide disparity in answers you're getting.

You actually asked what the difference is between lambdas and delegates in the .NET framework; that might be one of a number of things. Are you asking:

  • What is the difference between lambda expressions and anonymous delegates in the C# (or VB.NET) language?

  • What is the difference between System.Linq.Expressions.LambdaExpression objects and System.Delegate objects in .NET 3.5?

  • Or something somewhere between or around those extremes?

Some people seem to be trying to give you the answer to the question 'what is the difference between C# Lambda expressions and .NET System.Delegate?', which doesn't make a whole lot of sense.

The .NET framework does not in itself understand the concepts of anonymous delegates, lambda expressions, or closures - those are all things defined by language specifications. Think about how the C# compiler translates the definition of an anonymous method into a method on a generated class with member variables to hold closure state; to .NET, there's nothing anonymous about the delegate; it's just anonymous to the C# programmer writing it. That's equally true of a lambda expression assigned to a delegate type.

What .NET DOES understand is the idea of a delegate - a type that describes a method signature, instances of which represent either bound calls to specific methods on specific objects, or unbound calls to a particular method on a particular type that can be invoked against any object of that type, where said method adheres to the said signature. Such types all inherit from System.Delegate.

.NET 3.5 also introduces the System.Linq.Expressions namespace, which contains classes for describing code expressions - and which can also therefore represent bound or unbound calls to methods on particular types or objects. LambdaExpression instances can then be compiled into actual delegates (whereby a dynamic method based on the structure of the expression is codegenned, and a delegate pointer to it is returned).

In C# you can produce instances of System.Expressions.Expression types by assigning a lambda expression to a variable of said type, which will produce the appropriate code to construct the expression at runtime.

Of course, if you were asking what the difference is between lambda expressions and anonymous methods in C#, after all, then all this is pretty much irelevant, and in that case the primary difference is brevity, which leans towards anonymous delegates when you don't care about parameters and don't plan on returning a value, and towards lambdas when you want type inferenced parameters and return types.

And lambda expressions support expression generation.

James Hart
Great info! You inspired me to fire up reflector and look at the IL. I didn't know lambdas resulted in generated classes, but it makes perfect sense now that I think about it.
Chris Ammerman