Lambda Expressions and closures Part 2


 

In my previous post, I have spoken about Lambdas. Now I will move to closures.

Wikipedia defines it as

In computer science, a closure (also lexical closure or function closure) is a function or reference to a function together with a referencing environment

In essence, a closure is a block of code which can be executed at a later time, but which maintains the environment in which it was first created – i.e. it can still use the local variables etc of the method which created it, even after that method has finished executing. The general feature of closures is implemented in C# by anonymous methods and lambda expressions.

So basically closure is the code and the supporting data environment  .Now to understand it through an example.

static void Main(string[] args)

{

int x = 0, y = 1, z = 3;

Delegate d;

// int i = 0;

d = (Action)(() => { Console.WriteLine(“Hello”);

x++;

y++;

z++;

Console.WriteLine(x+” “+y+” “+z+ ” “);

Console.Read();

 

});

d.DynamicInvoke();

}

So variable become our data. Now the compiler sees that the lambda expression references data. Now as the generic definition goes, the compiler needs to close or make a closure containing all the referenced variables.

Now the common question is how the compiler passes these data to the sealed class that it generates? (If you have read my previous post, you should be familiar with how the compiler generates classes when it encounters lambda expressions)

These data are passed by reference.

Now to see what exactly is done by the compiler.

My original program is

class Program

{

static int x = 0;

static void Main(string[] args)

{

int  y = 1, z = 3;

Delegate d;

d = (Action)(() => { Console.WriteLine(“Hello”);

x++;

y++;

z++;

Console.WriteLine(x+” “+y+” “+z+ ” “);

Console.Read();

 

});

d.DynamicInvoke();

}

 

}

I have made my x a global variable.Now lets see what the compiler does

 

[CompilerGenerated]

private sealed class <>c__DisplayClass1

{

public int y;

public int z;

 

public void <Main>b__0()

{

Console.WriteLine(“Hello”);

Program.x++;

this.y++;

this.z++;

Console.WriteLine(string.Concat(new object[] { Program.x, ” “, this.y, ” “, this.z, ” ” }));

Console.Read();

}

}

Thus the compiler creates a shared object. Everyone refers to the same object.The compiler basically makes a new instance of the classes and initializes the instances of the generated class based on the given values. Thus all references to the data refers to the same field within a shared object.

 

Advertisements

One response to “Lambda Expressions and closures Part 2

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s