【问题标题】:Can't see how the compiler uses the classes he creates for my closures看不到编译器如何使用他为我的闭包创建的类
【发布时间】:2011-11-08 14:53:43
【问题描述】:

我编写了这个非常基本的程序来检查编译器在幕后所做的事情:

class Program
{
    static void Main(string[] args)
    {
        var increase = Increase();
        Console.WriteLine(increase());
        Console.WriteLine(increase());
        Console.ReadLine();
    }

    static Func<int> Increase()
    {
        int counter = 0;
        return () => counter++;
    }
}

现在,当我使用 Reflector 查看代码时,我确实看到编译器为我的闭包生成了一个类,如下所示:

[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
    // Fields
    public int counter;

    // Methods
    public int <Increase>b__0()
    {
        return this.counter++;
    }
}

没关系,我知道他需要这样做来处理我的关闭。但是,我看不到他实际上是如何使用这个类的。我的意思是我应该能够在某处找到实例化“c__DisplayClass1”的代码,我错了吗?

编辑

如果我点击增加方法,它看起来像这样:

private static Func<int> Increase()
{
    int counter = 0;
    return delegate {
        return counter++;
    };
}

【问题讨论】:

  • 你能把剩下的编译代码贴出来吗?尤其是你的 Main 方法。
  • @dowhilefor:Main 方法实际上会很无聊。它只是调用一个方法来获取委托,调用委托几次并打印出结果,然后调用Console.ReadLine

标签: c# compiler-construction reflector


【解决方案1】:

你应该在Increase 方法中找到它,我希望它有一个实现如下:

// Not actually valid C# code because of the names...
static Func<int> Increase()
{
    <>c__DisplayClass1 closure = new c__DisplayClass1();
    closure.counter = 0;
    return new Func<int>(closure.<Increase>b__0);
}

Reflector 不会向您显示该代码,除非您关闭它的优化,但它应该在那里。要么关闭 Reflector 的优化,要么使用 ildasm。

【讨论】:

  • 我希望它看起来像那样,但事实并非如此。我需要购买反射器的商业版本才能看到它吗?
  • 抱歉,蜜蜂转储,但我该如何关闭它的优化?我找不到它。我正在使用 Resharper 6.8.2.5 顺便说一句。
  • @Cristoph:关闭 Reflector 的优化通常对我有用(或将级别设置为 .NET 1.1)。您是否尝试过只查看 IL?
  • @Cristoph:在我使用的版本中,语言选择框的右侧有一个下拉菜单。它曾经处于称为优化的偏好之下。
  • 在我的版本中隐藏在选项中,但它就在那里。如果我将它调整为 .NET 1.0,我会看到它是如何被使用的。但只是为了做对。当您针对不同的 .NET 版本时,编译器会生成不同的代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多