在C#中,<>的意义是什么?

32

我正在学习C#,遇到了一段代码不理解,希望您能为我澄清一下。

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

<>代表什么?为什么前面有一个.(点)?


2
这是反编译的代码吗? - Soner Gönül
3个回答

39

您正在查看一些反编译的代码-具体来说,是由编译器生成的代码。

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

为什么编译器生成此代码因情况而异-它可能是Lambda、迭代器或异步块的实现,还可能是其他原因。


希望您的另一个问题也得到了回答-通常有一个.前缀,以分隔命名空间部分,或更可能的情况是将嵌套类的名称与封闭类的名称分开。


1
可能还有其他原因。 我想通用声明会编译成类似的东西。 - James
2
@James - 不确定你在这里想表达什么。泛型是CLR中的一级概念。Lambda表达式、迭代器块等都是编译器技巧,会产生额外的代码需要放入类中。 - Damien_The_Unbeliever
我想表达的是,当通用代码被编译时,可能会产生类似于OP所提到的代码。 - James
2
@James,这是可以想象的,但实际上,泛型类型的IL表示看起来非常不同。值得注意的是,没有涉及到<>字符。 - phoog

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”。


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

@Eric 也来回答这个问题了。 - Ehsan Sajjad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接