Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
625 views
in Technique[技术] by (71.8m points)

compiler construction - What are C# lambda's compiled into? A stackframe, an instance of an anonymous type, or?

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

I've read this question. Which mostly answers "why" you can't use a lambda when also using implicit type features. But, this question is aimed at answering what construct the compiler produces to actually carry out the code of a lambda. Is it a method call of an anonymous type (something like anonymous types that implement an interface in Java?) or is it just a stack frame with references to closed variables and the accepting the parameter signature? Some lambda's don't close over anything -- so are there then 2 different resulting outputs from the compile.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...