!0がMicrosoft Intermediate Language(MSIL)の型なのはなぜですか?


88

多くのMSILリストで、次のことを確認しました。

System.Nullable`1<!0> etc ...

または

class !0 etc ...

!0これらの状況での意味は何ですか?

回答:


118

これは、.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」と読みます。または、より優れた逆コンパイラを使用します。


35

これはジェネリック型パラメーターです。

それらは定位置です。

いくつかの汎用コードを逆コンパイルして、それらの使用方法を確認します(ILとC#を比較してください)。


5
私はTryRoslyn Iを使用している場合、それは...得ることはありませんgoo.gl/ZZKE38私が手に!Tして!!T、私がILDASMを使用している場合...同じことを、一般的なパラメータを含むクラスのメソッドまたはであるかによって
ザナトス

@xanatos常にではありません。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も使用します。
Luaan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.