多くのMSILリストで、次のことを確認しました。
System.Nullable`1<!0> etc ...
または
class !0 etc ...
!0
これらの状況での意味は何ですか?
回答:
これは、.NETアセンブリの確認に使用する逆コンパイラの癖です。これはildasm.exeの動作であり、ReflectorやILSpyなどの他のものはこれを正しく行います。それを書いたMicrosoftプログラマーはショートカットをとり、メタデータで型引数名を検索する追加のコードを記述せずに、エンコードされた方法で型引数を表示するだけの文字列をILから生成しました。
!n
ジェネリック型のn番目の型引数として読み取る必要があります。ここで、!0は「最初の型の引数」を意味し、!1は「2番目の型の引数」を意味します。Nullable <>の場合、MSDN記事の「!0」は「T」を意味することがわかります。
のようなものに遭遇することもあり!!T
ます。2つの感嘆符は、ジェネリックメソッドの型引数を示します。今回は、ildasm.exe はを使用する代わりに型引数名を検索します!!0
。プログラマがジェネリック型ではなくジェネリック型のショートカットを採用した理由は、リバースエンジニアリングが難しいことです。Ildasmはかなり風変わりなプログラムであり、.NETの他のC ++コードとは非常に異なるC ++コーディングスタイルで記述されています。これはインターンの割り当てであったという規律のある、ゼロ以外のオッズではありません:)
「Nullable」の `1サフィックスは、ジェネリック型名の通常のエンコーディングです。これは、ジェネリック型に型引数が1つあることを示します。つまり、Nullable <>の場合、!1が使用されていることはありません。
したがって、単に!0
「T」と読みます。または、より優れた逆コンパイラを使用します。
これはジェネリック型パラメーターです。
それらは定位置です。
いくつかの汎用コードを逆コンパイルして、それらの使用方法を確認します(ILとC#を比較してください)。
ldfld class System.Collections.Generic.Dictionary``2<!0, !1> valuetype System.Collections.Generic.Dictionary``2/Enumerator<!TKey, !TValue>::dictionary
またはのようなコードも表示されますcall instance void class System.Collections.Generic.Dictionary``2<!TKey, !TValue>::Insert(!0, !1, bool)
。とにかく、生のILは位置引数のみを使用します-これ!TKey
はすでにILを読みやすくするための試みです。多分それはいつもうまくいくとは限らないのですか?ECMA仕様では常に定位置!0
/ !00
も使用します。
!T
して!!T
、私がILDASMを使用している場合...同じことを、一般的なパラメータを含むクラスのメソッドまたはであるかによって