显示编译器生成的关闭代码

时间:2018-04-18 12:22:30

标签: c# closures

我创建了一个小型的测试类:

public delegate int Adder();

class Example {
    static Adder CreateAdder() {
        int x = 0;
        return delegate {
            x++;
            return x;
        };
    }

    public static void Test() {
        Adder add = CreateAdder();
        Console.WriteLine(add());
        Console.WriteLine(add());
        Console.WriteLine(add());
    }
}

x是闭包变量。现在,我可以看看Reflector,编译器生成以下helper-class:

[CompilerGenerated]
private sealed class <>c__DisplayClass0_0 {
   public int x;
   internal int <CreateAdder>b__0() {
       int x = this.x;
       this.x = x + 1;
       return this.x;
   }
}

但是我看不出,这个Helper-Class将如何在测试方法中使用。是否有可能使用Helper-Class显示测试方法?

1 个答案:

答案 0 :(得分:0)

事实上,令人兴奋的部分不在Test()。因为Test()只是调用委托(add)。

// decompiled code is the same as original source
public static void Test()
{
  Adder add = Example.CreateAdder();
  Console.WriteLine(add());
  Console.WriteLine(add());
  Console.WriteLine(add());
}

编译器生成的类用于CreateAdder()

private static Adder CreateAdder()
{
  Example.<>c__DisplayClass0_0 cDisplayClass00 = new Example.<>c__DisplayClass0_0();
  cDisplayClass00.x = 0;
  return new Adder((object) cDisplayClass00, __methodptr(<CreateAdder>b__0));
}

因此,要创建委托,将实例化编译器生成的类的对象。委托以这个对象为目标,它是<CreateAdder>b__0方法(代表你在匿名方法中所做的)。

我用JetBrain's dotPeek反编译它。 ILDASM是Microsoft的替代方案。