【问题标题】:Show Compiler Generated Code for Closure显示编译器生成的闭包代码
【发布时间】:2018-04-18 12:22:29
【问题描述】:

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

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 看一下,编译器会生成以下帮助类:

[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 来显示测试方法?

【问题讨论】:

  • 您可以使用 ILDASM 或 JetBrain 的 dotPeek 来反编译您的程序集并查看 Test() 中发生了什么。

标签: c# closures


【解决方案1】:

其实,精彩的部分不在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));
}

所以为了创建委托,编译器生成的类的一个对象被实例化。并且委托以这个对象为目标,它是&lt;CreateAdder&gt;b__0 方法(代表您在匿名方法中所做的事情)。


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

【讨论】:

猜你喜欢
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
  • 2014-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多