什么是C#lambda的编译?一个堆栈框架,一个匿名类型的实例,或?

luc*_*iet 15 c# compiler-construction lambda

什么是C#lambda的编译?一个堆栈框架,一个匿名类型的实例,或?

我读过这个问题.这主要回答"为什么"在使用隐式类型功能时不能使用lambda.但是,这个问题的目的是回答编译器生成的构造实际执行lambda的代码.它是一个匿名类型的方法调用(类似于在Java中实现接口的匿名类型吗?),还是只是一个堆栈框架,它引用了闭合变量并接受了参数签名?有些lambda不会关闭任何东西 - 因此编译中有两个不同的结果输出.

Mar*_*ell 18

假设你的意思是"作为委托",那么它仍然取决于:p如果它捕获任何变量(包括"this",这可能是隐含的)那么这些变量实际上是作为编译器生成的类型的字段实现的(不公开任何地方),语句体成为该捕获类的方法.如果有多个捕获级别,则外捕获也是内捕获类的一个字段.但基本上:

int i = ...
Func<int,int> func = x => 2*x*i;
Run Code Online (Sandbox Code Playgroud)

就好像;

var capture = new SecretType();
capture.i = ...
Func<int,int> func = capture.SecretMethod;
Run Code Online (Sandbox Code Playgroud)

哪里:

class SecretType {
    public int i;
    public int SecretMethod(int x) { return 2*x*i; }
}
Run Code Online (Sandbox Code Playgroud)

这与"匿名方法"相同,但语法不同.

请注意,不捕获状态的方法可以实现为没有捕获类的静态方法.

另一方面,表达树......解释起来比较棘手:p

但是(我没有编译器,所以请耐心等待):

int i = ...
Expression<Func<int,int>> func = x => 2*x*i;
Run Code Online (Sandbox Code Playgroud)

是这样的:

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);
Run Code Online (Sandbox Code Playgroud)

(除了使用不存在的"memberof"构造,因为编译器可以作弊)

表达式树很复杂,但可以解构和检查 - 例如转换为TSQL.