views:

172

answers:

5

I have been trying to figure this out for quite sometime (reading online blogs and articlaes), but so far unsuccessful.

What are delegates? What are Lambda Expressions? Advantages and disadvantages of both? Possible best practice of when to use one or the other?

Thanks in advance.

+3  A: 

Delegate is an object that hold a reference to a function. Several different delegates may point to the same function. A delegate's type defines the footprint of a function it may point to.

Lambda expression is a function that doesn't have name. The only way to execute this function is to have a delegate pointing to the function. Lambda expressions are usually defined in place where you need a delegate to a function with a given footprint. This is useful to make code less verbose and at the same time more descriptive and flexible

I would suggest that you use a named function and a delegate to it whenever you have some code that is going to be called from different places. A common example is an event listener that you want to attach to several event producers.

Another point to consider writing a separate function is the complexity of the code. It isn't going to help anyone if you write a whole program inside a lambda expression.

On the other hand, you often need some trivial processing that you want to be executed in a callback manner. This is the point where you might love the lambda expressions.

What is very nice about lambda expressions that they inherit the scope they were defined in, so that you can easily your variables inside the lambda expression, and thus pass a lot of info inside. You should be careful though, see the Remarks section of this article.

Labdas are brilliant in conjunction with LINQ.

To conclude, I have to quote yet another must-read msdn section:

When you use method-based syntax to call the Where method in the Enumerable class (as you do in LINQ to Objects and LINQ to XML) the parameter is a delegate type System.Func. A lambda expression is the most convenient way to create that delegate. When you call the same method in, for example, the System.Linq.Queryable class (as you do in LINQ to SQL) then the parameter type is an System.Linq.Expressions.Expression where Func is any Func delegates with up to sixteen input parameters. Again, a lambda expression is just a very concise way to construct that expression tree. The lambdas allow the Where calls to look similar although in fact the type of object created from the lambda is different.
ULysses
@ULysses, thanks for the info. Can you provide examples of when you would use a delegate and when you would use a Lambda Expression?
user279521
+7  A: 

Delegates are methods that you can use as variables, like strings etc. For example you can declare a delegate method with one argument:

delegate void OneArgumentDelegate(string argument);

It doesn't do anything, much like an interface. If you have a method in any class with one argument like this:

void SomeMethod(string someArgument) {}

It matches the signature of the delegate, and thus can be assigned to a variable of its type:

OneArgumentDelegate ThisIsAVariable = new OneArgumentDelegate(SomeMethod);
OneArgumentDelegate ThisIsAlsoAVariable = SomeMethod; // Shorthand works too

These can then be passed as arguments to methods and invoked, like so:

void Main()
{
  DoStuff(PrintString);
}

void PrintString(string text)
{
  Console.WriteLine(text);
}

void DoStuff(OneArgumentDelegate action) 
{
  action("Hello!");
}

This will output Hello!.

Lambda expressions are a shorthand for the DoStuff(PrintString) so you don't have to create a method for every delegate variable you're going to use. You 'create' a temporary method that's passed on to the method. It works like this:

DoStuff(string text => Console.WriteLine(text)); // single line
DoStuff(string text => // multi line
{
  Console.WriteLine(text);
  Console.WriteLine(text);
});

Lambda expressions are just a shorthand, you might as well create a seperate method and pass it on. I hope you understand it better now ;-)

Jouke van der Maas
It is unnecessary in most cases to declare the type of the input variable in the lambda expression, and IMO, makes code necessarily verbose (something the lambda expression was trying to solve in the first place. DoStuff(txt => Console.WriteLine(txt)) is equally sufficient.
Chris
+1 A decent explanation - certainly better than most I have seen on-line.
CJM
@Chris I thought about leaving it out but decided against it for clarity. Leaving it out here could've confused people that aren't familiar with the syntax. In 'real' code, I usually leave it out though, as you suggest.
Jouke van der Maas
@Jouke van der Maas: to say that lambda is shorthand for `DoStuff(PrintString)` might be unfortunate in the choice of examples though. Consider that `DoStuff(text => Console.WriteLine(text));` is only a more verbose way of writing `DoStuff(Console.WriteLine);` since your lambda has the exact same signature as `Console.WriteLine`: they are both a method that takes a string and return nothing.
David Hedlund
@David You're right, of course, but I didn't want to use any complex examples in this. Could've done better, sure, but for the purpose I think this will do.
Jouke van der Maas
+1  A: 

Delegate is just pointer to function. Its just like a "variable", where you can save address to another function that will be called

    public class test {
    Action<int> CallUserCode;

    public test(Action<int> proc){
        CallUserCode = proc;
    }

    void foo(){
        int someValue = 0;
        //do some stuff that needs to call the user procedure
        CallUserCode(someValue);
    }
}

Lambda Expressions is too a delegate, which has simplified syntax and can "create" functions "inline". So the previous example would be called using lambda in following way.

void bar(){
    var t = new test(x => { /* do something with the value i get from foo */});
    t.foo();  //here function foo gets called, which will call 'do something' AND call my lambda expression
}
Markos
+2  A: 

As the others said, lambdas are a syntax to create delegates inline and anonymously. One thing you can do with lambdas that is not possible with traditional functions are closures. This way you can create functions at runtime with runtime information:

string mystring = SomeObject.GetMyString();
AnotherObject.OnSomeEvent += (eventparams => 
{
  string newstring = string.Format(eventparams.Message, mystring);
  SomeService.PrintEvent(newstring);
}

This way, mystring is incorporated into the delegate and can be used as a variable.

Ozan
You can create anonymous delegates, which are closures.
Gabe Moothart
+2  A: 

No one has mentioned anonymous delegates. You can create delegates on the fly, without declaring them:

public void Action(Func<int, int> func);
...
Action(delegate(int x) { return x*x; });

Which is just a more verbose version of the lambda syntax:

Action(x => x*x);

Also note that the lambda syntax has more aggressive type inference. Another difference is that the lambda notation can be used to declare expression trees:

public void Action(Expression<Func<int, int>>);
Action(x => x*x);

In which case what you get is not a function but a parse tree that you can examine at runtime. This is how linq queries build their sql, for example.

edit

To more directly answer the question of when to use one or the other:

You rarely need to declare a new delegate type yourself, although it is occasionally helpful. The framework provides several Func<> types, along with Action<T> and Predicate<T> which are usually all that you need.

When creating a function 'on the fly', there is no advantage to using the anonymous delegate syntax instead of the lambda syntax. Since the lambda syntax is more concise and type-inferred, prefer it.

Gabe Moothart
+1 for mentioning expression trees. While you don't need to understand them to *use* LINQ to SQL, they are an important feature of the language. Also, before lambdas were added in C# 3.0, the only way to get lambda-like semantics was to use anonymous delegates. I recall doing that a lot in C# 2.0 code.
Daniel Pryden