generics 型推論 - ランタイムまで型が不明な場合は、C#でジェネリックメソッドを使用できますか?





unity method (4)


なぜC#はそれが法的声明であることを許しませんか?

他の人が指摘しているように、あなたはこれをすることはできません。 何故なの? さて、あなたの例を考えてみましょう:

foreach(Type someType in listOfTypes)
{
    SomeMethod<someType>();
}

ランタイムまで型のリストの各型を知ることはできませんが、 SomeMethodの型パラメータはコンパイル時SomeMethodなければならないことにSomeMethodください。 コンパイラがあなたの呼び出しを解決するSomeMethod<T>SomeMethod<T>することは不可能なので、これは不正です。

C#4では、DLRをCLRに組み込むことでこれと他の多くの同様のことが可能になります。 特に、動的メソッド呼び出しは、コンパイル時に知られていないメソッドを呼び出すことを可能にします。

私が意味することを説明する最も簡単な方法は、コードサンプルです。 これはコンパイルされませんが、この効果を達成する方法はあります:

foreach(Type someType in listOfTypes)
{
    SomeMethod<someType>();
}

それがうまくいくのであれば本当に便利でしょうが、そうではありません。 上記と同じことを達成するための別の方法がありますか?それが法的声明であることをC#が許可しないのはなぜですか?

編集:これを行う唯一の方法のように私たちのニーズには遅すぎる可能性があります反射を介しているようだ。 なぜ効率的な方法が組み込まれていないのか、このようなものがC#4.0の作品にあるのかについての洞察はありますか?




反射を使用することができます。 現在のオブジェクトにSomeMethod()メソッドが含まれていると仮定すると、そうするコードは次のようになります。

GetType().GetMethod("SomeMethod").
    MakeGenericMethod(new Type[] { someType }).Invoke(this, null);

SomeMethod()が非公開である場合、コードは信頼性の低い環境では実行されないことに注意してください。







元の答えに加えて。 これは動作しますが、

MethodInfo method = typeof(Sample).GetMethod("GenericMethod");
MethodInfo generic = method.MakeGenericMethod(myType);
generic.Invoke(this, null);

また、 GenericMethodコンパイル時チェックを失うという点で少し危険GenericMethod 。 後でリファクタリングを行い、 GenericMethod名前を変更するGenericMethod 、このコードは気付かず、実行時に失敗します。 また、アセンブリの後処理(例えば、未使用のメソッド/クラスの難読化や削除など)がある場合、このコードも破損する可能性があります。

コンパイル時にリンクしているメソッドを知っていて、何百万回もコールされていないので、オーバーヘッドは問題にならないので、このコードを次のように変更します。

Action<> GenMethod = GenericMethod<int>;  //change int by any base type 
                                          //accepted by GenericMethod
MethodInfo method = this.GetType().GetMethod(GenMethod.Method.Name);
MethodInfo generic = method.MakeGenericMethod(myType);
generic.Invoke(this, null);

あまりかわいらしくはありませんが、ここではGenericMethodコンパイル時の参照がありますGenericMethodをリファクタリングしたり、削除したり、何かをGenericMethod 、このコードは動作し続けます(少なくともGenericMethodを削除したGenericMethod )。

同じことをする他の方法は、新しいラッパークラスを作成し、それをActivator作成することです。 私は良い方法があるかどうかわからない。





c# generics types