类似于:How do closures work behind the scenes? (C#)
假设我们有代码:
static void Main(string[] args)
{
int i = 100;
Action d = () => { i++; };
d();
Console.WriteLine(i.ToString());
}
我们会看到结果" 101 "。
我知道如果匿名函数捕获局部变量,它会创建一个新类,其中包含局部变量的字段和与匿名函数相关的方法。
所以这个类看起来像(伪代码):
private class DisplayClass1
{
public int i;
public void Main(){ i++; }
}
使用ILDasm.exe,我们看到生成的类:
然后程序的主要方法看起来像(伪代码):
static void Main(string[] args)
{
int i = 100;
//create helper class
DisplayClass1 class1 = new DisplayClass1();
//initialize fields
class1.i = i;
//crete instance of delegate
Action d = new Action(class1.Main);
d.Invoke();
Console.WriteLine(i.ToString());
}
很明显它如何更改引用类型的实例。但它如何与struct一起使用?
我想它会在d.Invoke();
之后再添加一行i = class1.i;
(多线程的任何问题?)或者在DisplayClass1.Main
中执行一些特殊操作来从堆栈访问同一个变量。
这是此方法的IL代码:
.method public hidebysig instance void '<Main>b__0'() cil managed
{
// Code size 16 (0x10)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: dup
IL_0003: ldfld int32 ConsoleApplication3.Program/'<>c__DisplayClass1'::i
IL_0008: ldc.i4.1
IL_0009: add
IL_000a: stfld int32 ConsoleApplication3.Program/'<>c__DisplayClass1'::i
IL_000f: ret
} // end of method '<>c__DisplayClass1'::'<Main>b__0'
我不是MSIL的专家。有什么想法吗?
答案 0 :(得分:1)
您的伪代码不太对劲。它实际上用闭包类的字段替换了local的所有用法:
static void Main(string[] args)
{
//create helper class
DisplayClass1 class1 = new DisplayClass1();
//initialize fields
class1.i = 100;
//crete instance of delegate
Action d = new Action(class1.Main);
d.Invoke();
Console.WriteLine(class1.i.ToString());
}