Clearly, this is much simpler than the C# 1.0 version from last time. However, anonymous methods and lambda expressions are compile-time features; the CLR itself is not aware of them. How does this code work? How can an anonymous method use a local variable from its parent scope?

This is an example of a closure – a function bundled together with external variables that the function uses. The C# compiler handles this the same way that I did manually last time in C# 1: it generates a class to hold the function and the variables that it uses, then creates a delegate from the member function in the class. Thus, the local state is passed as the delegate’s this parameter.

To see how the C# compiler implements closures, I’ll use ILSpy to decompile the more-familiar C# 3 version: (I simplified the compiler-generated names for readability)

The ClosureClass (which was actually named <>c__DisplayClass1) is equivalent to the GreaterThan class from my previous example. It holds the local variables used in the lambda expression. Note that this class replaces the variables – in the original method, instead a local variable named x, the compiler uses the public x field from the ClosureClass. This means that any changes to the variable affect the lambda expression as well.

The lambda expression is compiled into the Lambda method (which was originally named <Main>b__0). It uses the same field to access the local variable, sharing state between the original outer function and its lambda expression.