C# 关闭。它如何改变结构类型的变量?

C# closure. How it changes the variable of struct type?

类似于: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”。

我知道,如果匿名函数捕获局部变量,它会创建一个新的 class,其中包含与匿名函数相关的局部变量和方法字段。

所以这个 class 看起来像(伪代码):

 private class DisplayClass1
 {
     public int i;            
     public void Main(){ i++; }
 }

使用 ILDasm.exe 我们看到生成了 class:

然后程序的主要方法将如下所示(伪代码):

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

很清楚它是如何改变引用类型的实例的。但是它如何与结构一起工作?

我猜它在 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 方面的专家。有什么想法吗?

您的伪代码不太正确。它实际上用闭包 class 的字段替换了所有对 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());
}