32

C# を勉強していて、理解できないコードを見つけました。あなたが私のためにそれを明確にしてくれることを望んでいました。

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

とはどういう<>意味ですか? そして、なぜその.前に(ドット)があるのですか?

4

3 に答える 3

39

逆コンパイルされたコード、具体的にはコンパイラによって生成されたものを見ています。

<>CLR 識別子がそのような文字で始まることは有効ですが、C# では無効であるため、コンパイラは(これは実装の詳細です) を使用します。そのため、名前が C# コード内の名前と競合しないことが保証されます。

コンパイラがこのコードを生成した理由はさまざまです。ラムダ、反復子、または非同期ブロックの実装である可能性があり、その他の理由もある可能性があります。


そして、うまくいけば、あなたの質問の他の部分も答え.られます.クラス。

于 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 に答える