Implementation of anonymous delegates in C#

What is the output of the following program?

int x = 5;

Action action = (() => { Console.WriteLine(x); });

x = 6;

action();



The output is of course 6, because delegates capture references to outer variables.

So how is this implemented in the compiler?
The compiler rewrites the code above to something like this:

Scope s = new Scope();

scope.x = 5;

Action action = (scope);

scope.x = 6;

scope.Call();


and defines the Scope class like this:

private sealed class Scope

{

    public int x;

 

    public Scope();

    public void Call()

    {

        Console.WriteLine(this.x);

    }

}



As we would expect, the is no way to create a reference to eg. an int in IL, so this is solved naturally - the int is wrapped inside Scope class and all accesses are done through the wrapper.
The wrapper also defines the Call method, which is exactly the body of the anonymous delegate.

Actually, the compiler generated name for our Scope class is "<>__DisplayClass1", and the Call method is named "<Main>b__0".

For a little more complex example, see this post on stackoverflow.

Posted by Martin Konicek on 4:18 PM

0 comments:

Post a Comment