What are C# lambda’s compiled into? A stackframe, an instance of an anonymous type, or?

Assuming you mean “as a delegate”, then it still depends :p if it captures any variables (including “this”, which may be implicit) then those variables are actually implemented as fields on a compiler-generated type (not exposed anywhere public), and the statement body becomes a method on that capture class. If there are multiple levels of capture, the outer capture is again a field on the inner capture class. But essentially:

int i = ...
Func<int,int> func = x => 2*x*i;

Is like;

var capture = new SecretType();
capture.i = ...
Func<int,int> func = capture.SecretMethod;

Where:

class SecretType {
    public int i;
    public int SecretMethod(int x) { return 2*x*i; }
}

This is identical to “anonymous methods”, but with different syntax.

Note that methods that do not capture state may be implemented as static methods without a capture class.

Expression trees, on the other hand… Are trickier to explain :p

But (I don’t have a compiler to hand, so bear with me):

int i = ...
Expression<Func<int,int>> func = x => 2*x*i;

Is something like:

var capture = new SecretType();
capture.i = ...
var p = Expression.Parameter("x", typeof(int));  
Expression<Func<int,int>> func = Expression.Lambda<Func<int,int>>(
    Expression.Multiply(
        Expression.Multiply(Expression.Constant(2),p),
        Expression.PropertyOrField(Expression.Constant(capture), "i")
    ), p);

(except using the non-existent “memberof” construct, since the compiler can cheat)

Expression trees are complex, but can be deconstructed and inspected – for example to translate into TSQL.

Leave a Comment