32

我正在学习 C# 并抓住了一段我看不懂的代码。我希望你能为我澄清它。

CreateCustomerTask.<>c__DisplayClass0 cDisplayClass0 =
         new CreateCustomerTask.<>c__DisplayClass0();

有什么<>意义?为什么.前面有一个(点)?

4

3 回答 3

39

您正在查看一些反编译的代码 - 特别是由编译器生成的代码。

编译器使用<>(这是一个实现细节),因为虽然 CLR 标识符以此类字符开头是有效的,但它在 C# 中无效 - 因此可以保证该名称不会与 C# 代码中的任何名称冲突。

编译器生成此代码的原因各不相同 - 它可能是 lambda、迭代器或异步块的实现,也可能是其他一些原因。


并且,希望您的问题的另一部分也得到解答-.出于通常的原因,它前面有一个-分隔命名空间部分,或者在这种情况下更有可能将嵌套类的名称与封闭类的名称分开班级。

于 2012-12-30T14:29:19.967 回答
34

正如其他人所指出的那样,您所看到的是编译器生成的故意合法的 C# 名称,因此没有人会意外(或故意!)导致名称冲突。

生成此名称的原因是:

class C
{
  void M()
  {
    int x = 1;
    Func<int, int> f = y=>x+y;
  }  
}

由编译器生成,就像您编写的一样:

class C
{
  private class DisplayClass
  {
    public int x;
    public int AnonymousMethod(int y)
    { 
      return this.x + y;
    }
  }
  void M()
  {
    C.DisplayClass d = new C.DisplayClass();
    d.x = 1;
    Func<int, int> f = d.AnonymousMethod;
  }
}

当然,正如您所发现的那样,所有名称都被故意弄乱了。

闭包类被称为“DisplayClass”的原因有点不幸:这是调试器团队用来描述在调试器中显示时具有特殊行为的类的行话。显然,当您调试代码时,我们不想将“x”显示为不可能命名的类的字段;相反,您希望它看起来像任何其他局部变量。调试器中有专门的设备来处理这种显示类。它可能应该被称为“ClosureClass”,以便更容易阅读反汇编。

于 2012-12-30T16:40:51.163 回答
10

使用Eric Lippert 的这个答案来解码名称,例如<>c__DisplayClass0. 根据答案中提供的表格,您正在查看一个匿名方法闭包类。不要依赖这在未来总是正确的,它是一个随时可能更改的实现细节。

于 2012-12-30T14:30:38.767 回答