2012-07-13 7 views
7

私はIL静的解析ツールを書いている、と私はジェネリック型パラメータが参照されている方法を規定する規則の理解に苦労抱えている:ILのジェネリックス - いつT!が使用されるかについてのルールは何ですか?

IList<T> interfaceから)このILを取る:

.property instance !T Item(
    int32 index 
) 
{ 
    .get instance !0 System.Collections.Generic.IList`1::get_Item(int32) 
    .set instance void System.Collections.Generic.IList`1::set_Item(int32, !0) 
} 

!Tの代わりに!0が表示されるのはなぜですか?私はそれらがVMが行く限り同等であると推測しますが、あなたが名前を持つことが保証されているときには、位置参照を使用するのは奇妙に思えます。

更新:KeyedCollection.ctorから追加の場合、:Common Language Infrastructure standard

IL_0037: newobj instance void class System.Collections.Generic.Dictionary`2<!TKey,!TItem>::'.ctor'(class System.Collections.Generic.IEqualityComparer`1<!0>) 
IL_003c: stfld class System.Collections.Generic.Dictionary`2<!0,!1> class System.Collections.ObjectModel.KeyedCollection`2<!0,!1>::dictionary 
+0

これは表示されません。あなたは逆アセンブラのバグではないと確信していますか? –

+0

うん、それは間違いなく、逆アセンブラ(この場合はモノラル)が生成しているものです。 Mono.Cecil(これは、より多くの書籍のメタデータに似ているようです)、例えば:stfld System.Collections.Generic.Dictionary'2 System.Collections.ObjectModel.KeyedCollection'2 ::辞書 – toshok

+0

@HansPassant ILを紹介するのにあなたは何を使っていますか? – casperOne

答えて

4

Partition II - Metadata and File Format、節7.1 "タイプ"、それは述べて:

Type ::=  Description 
--------  ----------- 
'!'    Generic parameter in a type definition, accessed by index from 0 

だから、短い答え:なぜならそれは仕様に入っています。

長い答え:これは私の見解ですが、基本的にほとんどのILコマンドはスタックベースであり、常に位置参照をパラメータとして使用しています。それは、ILにおける共通のパターン/使用メカニズムを維持するために、位置参照がジェネリックに使用されることは意味があります。

+0

だから '!T'はいつ使われますか? – svick

+0

@svickそうではありませんが、宣言にのみ使用されています。メタデータに名前が付いている点は型パラメータの名前を保持することですが、* used *では位置によってアクセスされます。 – casperOne

+0

これはまだかなり混乱しています。 !Tはプロパティの宣言で使用されますが、!0は同じ汎用パラメータを参照しています。私はちょうどそれらが完全に交換可能であると仮定するべきですか? – toshok