简体   繁体   English

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

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

What are C# lambda's compiled into? 什么是C#lambda的编译? 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. 这主要回答“为什么”在使用隐式类型功能时不能使用lambda。 But, this question is aimed at answering what construct the compiler produces to actually carry out the code of a lambda. 但是,这个问题的目的是回答编译器生成的构造实际执行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? 它是一个匿名类型的方法调用(类似于在Java中实现接口的匿名类型吗?),还是只是一个堆栈框架,它引用了闭合变量并接受了参数签名? Some lambda's don't close over anything -- so are there then 2 different resulting outputs from the compile. 有些lambda不会关闭任何东西 - 因此编译中有两个不同的结果输出。

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. 假设你的意思是“作为委托”,那么它仍然取决于:p如果它捕获任何变量(包括“this”,这可能是隐含的)那么这些变量实际上是作为编译器生成的类型的字段实现的(不公开任何地方),语句体成为该捕获类的方法。 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 另一方面,表达树......解释起来比较棘手: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) (除了使用不存在的“memberof”构造,因为编译器可以作弊)

Expression trees are complex, but can be deconstructed and inspected - for example to translate into TSQL. 表达式树很复杂,但可以解构和检查 - 例如转换为TSQL。

Lambda expressions are indeed anonymous functions, but with more versatility. Lambda表达式确实是匿名函数,但具有更多功能。 These two articles authored by the MSDN have a lot of information on lambda expressions, how to use them, what precedence the operator => has, what their relation to anonymous functions are, and some advanced suggestions of use. 这两篇由MSDN撰写的文章有很多关于lambda表达式的信息,如何使用它们,operator =>有什么优先级,它们与匿名函数的关系是什么,以及一些高级的使用建议。

Lambda Expressions (MSDN) Lambda表达式(MSDN)

=> Operator (MSDN) =>运营商(MSDN)

Here are some examples: 这里有些例子:

public class C
{
    private int field = 0;

    public void M()
    {
        int local = 0;

        Func<int> f1 = () => 0;
        // f1 is a delegate that references a compiler-generated static method in C

        Func<int> f2 = () => this.field;
        // f2 is a delegate that references a compiler-generated instance method in C

        Func<int> f3 = () => local;
        // f3 is a delegate that references an instance method of a compiler-generated nested class in C
    }
}

A lambda expression is an unnamed method written in place of delegate istance. lambda表达式是一种代替委托代理的未命名方法。 The compiler converts it to either: 编译器将其转换为:

  • A delegate instance 委托实例
  • An expression tree , of type Expression<TDelegate> that representing the code inside, in a traversable object model. Expression<TDelegate>类型的表达式树 ,表示可遍历对象模型中的代码。 This allows the lambda expression to be interpreted at runtime. 这允许在运行时解释lambda表达式。

So the compiler solves lambda expressions moving the expression's code into a private method. 因此,编译器解决了将表达式代码移动到私有方法中的lambda表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM