65

初期化の一部としてジェネリック型を取るクラスがあります。

public class AnimalContext<T>
{
    public DoAnimalStuff()
    {
        //AnimalType Specific Code
    }
}

私が今できることは、

AnimalContext<Donkey> donkeyContext = new AnimalContext<Donkey>();
AnimalContext<Orca> orcaContext = new AnimalContext<Orca>();

しかし、私が必要/やりたいことは、実行時にのみ認識される型に初期化された AnimalContext を宣言できるようにすることです。例えば、

Animal a = MyFavoriteAnimal(); //returns an instance of a class 
                               //implementing an animal
AnimalContext<a.GetType()> a_Context = new AnimalContext<a.GetType()>();
a_Context.DoAnimalStuff();

これは可能ですか?私はこれに対する答えをオンラインで見つけることができないようです。

4

3 に答える 3

64

この部分が意味すること可能です:

new AnimalContext<a.GetType()>();

明らかに、その正確な構文は間違っています。それについては後で説明しますが、型パラメーターがruntimeまでわからない場合、実行時にジェネリック型のインスタンスを構築することできます。

この部分の意味はのとおりです。

AnimalContext<a.GetType()> a_Context

つまり、コンパイル時に型パラメーターがわからない場合、変数をジェネリック型として型付けすることはできません。ジェネリックはコンパイル時の構成要素であり、コンパイル時に型情報を利用できることに依存しています。これを考えると、コンパイル時に型がわからない場合、ジェネリックのすべての利点が失われます。

ここで、実行時まで型がわからないときに実行時にジェネリック型のインスタンスを構築するには、次のように言えます。

var type = typeof(AnimalContext<>).MakeGenericType(a.GetType());
var a_Context = Activator.CreateInstance(type);   

コンパイル時の型a_contextobject. a_contextアクセスする必要があるメソッドを定義する型またはインターフェイスにキャストする必要があります。多くの場合、ここで人々が行うのは、ジェネリック型にAnimalContext<T>何らかのインターフェイスを実装させるIAnimalContext(たとえばAnimalContexta_context-ジェネリック基本クラス)。もう 1 つの方法は、 を使用することdynamicです。しかし、繰り返しになりますが、これを行う際にジェネリック型の利点はまったくないことに注意してください。

于 2013-07-08T04:15:19.010 に答える
11

MakeGenericTypeメソッドを使用してジェネリック型でリフレクションを使用し、dynamicキーワードを利用できます。

var type = typeof (AnimalContext<>).MakeGenericType(a.GetType());
dynamic a_Context = Activator.CreateInstance(type);

したがって、次のように呼び出すことができます。

a_Context.DoAnimalStuff();

または、リフレクションを再度使用してメソッドを呼び出します。

type.GetMethod("DoAnimalStuff").Invoke(a_Context, null);
于 2013-07-08T04:12:37.227 に答える
6

リフレクションを使用して型を作成し、その型を呼び出す必要があります。何かのようなもの:

Animal a = MyFavoriteAnimal();
var contextType = typeof(EsbRepository<>).MakeGenericType(a.GetType());

dynamic context = Activator.CreateInstance(contextType);
context.DoAnimalStuff();

dynamic を使用すると、実行時にコンテキスト変数が評価され、DoAnimalStuff メソッドを呼び出すことができるようになります。

于 2013-07-08T04:13:56.647 に答える