1. ホーム
  2. c#

[解決済み] VSデバッガの「マジックネーム」についての学習場所

2022-05-17 23:22:50

質問

Reflector を使用したことがあるなら、C# コンパイラーが、デバッガーによる「特別な」表示に値する型、メソッド、フィールド、およびローカル変数を生成することにおそらく気づいたでしょう。例えば、'CS$'で始まるローカル変数は、ユーザーには表示されません。その他にも、匿名メソッドのクロージャ型や自動プロパティのバッキングフィールドなど、特別な命名規則があります。

私の質問:これらの命名規則についてどこで学ぶことができますか?どなたか、いくつかのドキュメントについてご存知でしょうか。

私の目的は、PostSharp 2.0が同じ規約を使用するようにすることです。

どのように解決するのですか?

これらはコンパイラの実装の詳細であり、いつでも変更される可能性があります。(UPDATE: 参照 GeneratedNames.cs を参照してください; 以下の説明は多少古くなっています)。

しかし、私はいい人なので、ここにその詳細の一部を紹介します。

オプティマイザーによって削除される未使用のローカル変数がある場合、とにかくそのデバッグ情報を PDB に出力します。 私たちはサフィックスを貼り付けて __Deleted$ というサフィックスを付けて、ソースコードにはあるがバイナリにはないことをデバッガが認識できるようにしています。

コンパイラによって割り当てられた一時的な変数スロットは CS$X$Y というパターンで名前が付けられ、X は "一時的な種類" で、Y はこれまでに割り当てられた一時的な変数の数である。一時的な種類は

0 --> short lived temporaries
1 --> return value temporaries
2 --> temporaries generated for lock statements
3 --> temporaries generated for using statements
4 --> durable temporaries
5 --> the result of get enumerator in a foreach
6 --> the array storage in a foreach
7 --> the array index storage in a foreach.  

8から264までの一時的な種類は、多次元配列のための追加の配列インデックスストレージです。

264以上の一時的な種類は、文字列を固定する固定文を含む一時的なもののために使用されます。

コンパイラが生成する特別な名前は、以下のために生成されます。

1 --> the iterator state ("state")
2 --> the value of current in an iterator ("current")
3 --> a saved parameter in an iterator
4 --> a hoisted 'this' in an iterator ("this")
5 --> a hoisted local in an iterator
6 --> the hoisted locals from an outer scope
7 --> a hoisted wrapped value ("wrap")
8 --> the closure class instance ("locals")
9 --> the cached delegate instance ("CachedAnonymousMethodDelegate")
a --> the iterator instance ("iterator")
b --> an anonymous method
c --> anonymous method closure class ("DisplayClass")
d --> iterator class
e --> fixed buffer struct ("FixedBuffer")
f --> anonymous type ("AnonymousType")
g --> initializer local ("initLocal")
h --> query expression temporary ("TransparentIdentifier")
i --> anonymous type field ("Field")
j --> anonymous type type parameter ("TPar")
k --> auto prop field ("BackingField")
l --> iterator thread id
m --> iterator finally ("Finally")
n --> fabricated method ("FabricatedMethod")
o --> dynamic container class ("SiteContainer")
p --> dynamic call site ("Site")
q --> dynamic delegate ("SiteDelegate")
r --> com ref call local ("ComRefCallLocal")
s --> lock taken local ("LockTaken")

魔法名を生成するパターンは P<N>C__SI というところです。

  • Pはキャッシュされたデリゲートとディスプレイクラスインスタンスの場合はCS$、それ以外は空です。
  • N は、もしあれば、その物に関連する元の名前です。
  • C は、上記の 1 から s までの文字です。
  • S は説明用のサフィックス("current", "state" など)で、メタデータを読むときに上の表を覚えておく必要がないようにするためです。
  • I はオプションの一意の番号です。