当我在C#编译器遇到一些非常奇怪的代码时,我正在回答关于闭包(合法地)延长对象生命周期的可能性的问题(如果重要的话,那就是4.0).
我能找到的最短的repro如下:
结果:编译器创建一个闭包对象,该对象引用创建lambda的对象,当它没有理由时 - 委托的"内部"目标是静态方法,并且lambda-creation-object的实例成员不需要在委托执行时被(并且没有)触摸.实际上,编译器的行为就像程序员this
无缘无故地捕获的那样.
class Foo
{
private Action _field;
public void InstanceMethod()
{
var capturedVariable = Math.Pow(42, 1);
_field = () => StaticMethod(capturedVariable);
}
private static void StaticMethod(double arg) { }
}
Run Code Online (Sandbox Code Playgroud)
发布版本生成的代码(反编译为'simpler'C#)如下所示:
public void InstanceMethod()
{
<>c__DisplayClass1 CS$<>8__locals2 = new <>c__DisplayClass1();
CS$<>8__locals2.<>4__this = this; // What's this doing here?
CS$<>8__locals2.capturedVariable = Math.Pow(42.0, 1.0);
this._field = new Action(CS$<>8__locals2.<InstanceMethod>b__0);
}
[CompilerGenerated]
private sealed class …
Run Code Online (Sandbox Code Playgroud)