C# lambda 编译成什么?堆栈帧,匿名类型的实例,还是? [英] What are C# lambda's compiled into? A stackframe, an instance of an anonymous type, or?

查看:20
本文介绍了C# lambda 编译成什么?堆栈帧,匿名类型的实例,还是?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C# lambda 编译成什么?堆栈帧、匿名类型的实例,还是?

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

我已阅读此问题.这主要回答了为什么"在使用隐式类型功能时不能使用 lambda.但是,这个问题旨在回答编译器生成什么构造来实际执行 lambda 的代码.它是匿名类型的方法调用(类似于在 Java 中实现接口的匿名类型?)还是只是一个包含对封闭变量的引用和接受参数签名的堆栈帧?一些 lambda 不会关闭任何东西——所以编译时会有 2 个不同的结果输出.

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.

推荐答案

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

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;

就像;

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

地点:

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.

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

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;

类似于:

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);

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

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

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

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

这篇关于C# lambda 编译成什么?堆栈帧,匿名类型的实例,还是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆