【发布时间】:2018-01-02 10:15:21
【问题描述】:
为什么 C# 7 编译器将本地函数转换为与其父函数所在的同一类中的方法。而对于匿名方法(和 Lambda 表达式),编译器会为每个父函数生成一个嵌套类,该类将包含其所有匿名方法作为实例方法?
例如C#代码(匿名方法):
internal class AnonymousMethod_Example
{
public void MyFunc(string[] args)
{
var x = 5;
Action act = delegate ()
{
Console.WriteLine(x);
};
act();
}
}
会产生IL代码(匿名方法)类似于:
.class private auto ansi beforefieldinit AnonymousMethod_Example
{
.class nested private auto ansi sealed beforefieldinit '<>c__DisplayClass0_0'
{
.field public int32 x
.method assembly hidebysig instance void '<MyFunc>b__0' () cil managed
{
...
AnonymousMethod_Example/'<>c__DisplayClass0_0'::x
call void [mscorlib]System.Console::WriteLine(int32)
...
}
...
}
...
同时,C#代码(局部函数):
internal class LocalFunction_Example
{
public void MyFunc(string[] args)
{
var x = 5;
void DoIt()
{
Console.WriteLine(x);
};
DoIt();
}
}
会生成IL代码(局部函数)类似于:
.class private auto ansi beforefieldinit LocalFunction_Example
{
.class nested private auto ansi sealed beforefieldinit '<>c__DisplayClass0_0' extends [mscorlib]System.ValueType
{
.field public int32 x
}
.method public hidebysig instance void MyFunc(string[] args) cil managed
{
...
ldc.i4.5
stfld int32 LocalFunction_Example/'<>c__DisplayClass1_0'::x
...
call void LocalFunction_Example::'<MyFunc>g__DoIt1_0'(valuetype LocalFunction_Example/'<>c__DisplayClass1_0'&)
}
.method assembly hidebysig static void '<MyFunc>g__DoIt0_0'(valuetype LocalFunction_Example/'<>c__DisplayClass0_0'& '') cil managed
{
...
LocalFunction_Example/'<>c__DisplayClass0_0'::x
call void [mscorlib]System.Console::WriteLine(int32)
...
}
}
请注意,DoIt 函数已变成与其父函数在同一类中的静态函数。
此外,封闭的变量 x 已变成嵌套 struct 中的字段(不像匿名方法示例中那样嵌套 class)。
【问题讨论】:
-
尝试以实现本地方法的方式实现 lambda,看看会发生什么。
-
@Servy 你能告诉我怎么做吗?
-
你不能。这就是要点。
-
@Servy 这正是我要问的。为什么我(或编译器的人)不能像本地方法那样实现 lambda?
-
所以尝试使用与本地方法相同的方法来实现 lambda,看看为什么它不起作用。
标签: c# lambda cil anonymous-methods c#-7.0