6

次のような汎用メソッドがあるとします。

void Fun<T>(FunArg arg) {}

ジェネリック メソッドの異なるインスタンス化はありますthis.Fun<Feature>か?this.Fun<Category>

一般に、ジェネリック メソッドはどのようにインスタンス化されるのでしょうか? 異なるジェネリック引数が異なるメソッドを生成するか、実行時に使用される異なるメタデータとともに同じメソッドを生成しますか?

言語仕様からの引用で回答をサポートしてください。

また、私がこれらをしたとします:

client.SomeEvent += this.Fun<Feature>;   //line1
client.SomeEvent += this.Fun<Category>;  //line2
client.SomeEvent += this.Fun<Result>;    //line3

その後、

client.SomeEvent -= this.Fun<Feature>;   //lineX

lineXで行ったことを元に戻しますline1か? それとも他のものにも依存していますか?

4

3 に答える 3

5

これらはすべてメソッド定義を共有しますが、実行時には異なります。MethodInfoジェネリック型の引数がジェネリックメソッドを定義するためです。

裏付けとなるイラスト:

    Action<FunArg> a1 = Fun<X>;
    Action<FunArg> a2 = Fun<Y>;
    Action<FunArg> a3 = Fun<Y>;
    Console.WriteLine(a1.Method == a2.Method); // false
    Console.WriteLine(a3.Method == a2.Method); // true

JITレベルでは、より複雑です。参照は参照であるため、すべての参照型パラメーターは実装を共有Tします(そのようなものはすべて事前に制約を満たす必要があることに注意してください)。value-typeがある場合T、ジェネリック型引数のすべての組み合わせは、実行時に個別の実装を取得します。これは、それぞれが異なる最終実装を必要とするためです。

于 2012-04-23T10:46:59.470 に答える
4

関係するタイプによって異なります。

すべての参照型(つまり、クラス)について、1つのメソッドがそれらすべてを処理するためにJITされます。

すべての値型(つまり、 structs)について、型ごとに1つのメソッドがJITされます。

Featureしたがって、質問の情報は、とが参照型である場合、答えるのに十分詳細ではありませんCategory。そうです、1つのメソッドがそれらに対してJITされます。それらの一方または両方が値型である場合、値型ごとに1つのメソッドがJITされます。

ここでJITtedという単語を使用していることに注意してください。コンパイルされたアセンブリでは、メソッドは1つだけですが、実行時に、JITterは上記のルールに従ってジェネリックメソッドの実際の実装を作成します。

ポップクイズNGEN:ジェネリック型/メソッドを使用するアセンブリで使用するとどうなりますか?(ヒント:あなたが思っていることではありません

于 2012-04-23T10:46:43.713 に答える
0

はい、それらは 2 つの別々の方法になります。

于 2012-04-23T10:42:15.500 に答える