问题描述
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 编译成什么?堆栈帧,匿名类型的实例,还是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!