Lambda Expressions and closures


For any new developers the concept of Lambda and closures is quite confusing. The confusion results as the documentation and the examples are not very clear on what exactly happens behind the scene.

Lambda s are basically unnamed blocks of code.

( Parameters )=>

{

//lines of code

}

We are basically used to seeing a function name before the brackets and hence that is why I used the term unnamed. But basically we can think of lambda as a shortcut for anonymous delegates.

Instead of doing something like

delegate() { Console.WriteLine("Hello World"); Console.Read(); }
//we can write
    () => { Console.WriteLine("Hello");
                Console.Read(); 
            });

Both of them are equivalent .

Now suppose if you want to do this

d = (() => { Console.WriteLine("Hello");
                Console.Read(); 
            });

you will get an Cannot convert lambda expression to type ‘System.Delegate’ because it is not a delegate type Error. This error adds to the confusion as we knew lambda expression to be just a new syntax for anonymous methods and anonymous methods are inline delegates.

The fact is knowing the signature isn’t enough. We need to cast the lambda expression explicitly to the correct delegate type.

d = (Action)(() => { Console.WriteLine("Hello");
                Console.Read();

This is the proper way to do it. Now to understand lambda expressions we must go behind the scenes.

Lambda Expressions are equivalent to custom classes + delegates. Yes! That is exactly what Visual Studio generates when it encounters a lambda expression.

For the above expression Visual Studio will generate

 private sealed class randomClass_0
    {
        private static void b__0()
        {
            Console.WriteLine("Hello");
            Console.Read();
        }
    }

Now the void method is generated as we had not passed any parameters. Thus we have our custom class generated.

The custom generated delegate is

[CompilerGenerated]
private static Action CS$<>9__CachedAnonymousMethodDelegate1;

This brings us to the end of part 1 ,which primarily dealt with delegates. I will leave you with a picture in which I dissected the program through the reflector tool, so that I can see the compiler

image

The highlighted part shows the compiler generated stuff. Now you see ‘Main’ because I have done this in my Main() function.

If you want to test the code, here it is.

static void Main(string[] args)
        {
            Delegate d;
           // int i = 0;
            d = (Action)(() => { Console.WriteLine("Hello");
                Console.Read(); 
            });
    d = (Action)(delegate() { Console.WriteLine("Hello World"); Console.Read(); });
    d.DynamicInvoke();
        }

3 responses to “Lambda Expressions and closures

  1. Pingback: Lambda Expressions and closures Part 2 « Using Abhik.Mitra.myThoughts;

  2. Pingback: Asynchronous Programming Series « Using Abhik.Mitra.myThoughts;

  3. Write more, thats all I have to say. Literally, it seems as
    though you relied on the video to make your point.
    You clearly know what youre talking about, why throw away your intelligence on just
    posting videos to your weblog when you could be giving
    us something enlightening to read?

Leave a reply to Prince William Cancel reply