Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Lambda expressions and delegates [closed]

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.

like image 809
user279521 Avatar asked Jul 19 '10 14:07

user279521


People also ask

Is a lambda expression a delegate?

Lambda expressions are also examples of delegates, which are collections of lines of code that can take inputs and optionally return outputs. We use the type Func<T> to define delegates that return an output, and Action<T> for delegates that will not return an output.

Why a lambda expression forms a closure?

a function that can be treated as an object is just a delegate. What makes a lambda a closure is that it captures its outer variables. lambda expressions converted to expression trees also have closure semantics, interestingly enough.

What is the difference lambdas and delegates?

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.

Are closures and lambda the same?

A lambda expression is an anonymous function and can be defined as a parameter. The Closures are like code fragments or code blocks that can be used without being a method or a class. It means that Closures can access variables not defined in its parameter list and also assign it to a variable.


4 Answers

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 ;-)

like image 70
Jouke van der Maas Avatar answered Sep 28 '22 08:09

Jouke van der Maas


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.
like image 32
ULysses Avatar answered Sep 28 '22 08:09

ULysses


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.

like image 26
Gabe Moothart Avatar answered Sep 28 '22 10:09

Gabe Moothart


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
}
like image 38
Markos Avatar answered Sep 28 '22 10:09

Markos