2009-09-21 41 views
8

実行時に既知の型パラメータを持つクラスのジェネリックメソッドを呼び出すことに関する質問があります。具体的には実行時に型パラメータが指定されたジェネリック関数を呼び出す

は、コードはそうのようになります。


FieldInfo[] dataFields = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance); 

// data is just a byte array used internally in DataStream 
DataStream ds = new DataStream(data); 

foreach (FieldInfo field in dataFields) 
{ 
    Type fieldType = field.FieldType; 

    // I want to call this method and pass in the type parameter specified by the field's type 
    object objData = (object) ds.Read<fieldType>(); 
} 

読む()関数は、そのようになっています


public T Read() where T : struct 

この機能の目的は、バイト配列から読み出されたデータを返すことです。

このように実行時に汎用メソッドを呼び出す方法はありますか?

答えて

12

これは、単一の種類のパラメータで読み取り機能の非ジェネリックオーバーロードを作ることであろう処理するための最も簡単な方法:非ジェネリックバージョンを呼び出す

public object Read(Type t) 

そしてジェネリック版を持っている:

public T Read<T>() where T : struct 
{ 
    return (T)Read(typeof(T)) 
} 
+0

返信いただきありがとうございます。私はこのようなシンプルなデザイン変更を考慮しませんでした。 –

+0

私の問題はOPの質問のようには見えませんでしたが、あなたは私が知る必要があったことを正確に実証しました。ありがとう! – KennyZ

7

あなたはMETHODINFOを構築し、Readメソッドを呼び出す必要があります:

MethodInfo method = typeof(DataStream).GetMethod("Read"); 
MethodInfo generic = method.MakeGenericMethod(fieldType); 
object objData = generic.Invoke(ds, null); 
+0

Reedさん、ありがとうございました。 –

1

リーのルートに行く方がいいでしょう。 Genericは設計時には、さまざまな種類のクラスの共通コードを記述する必要がないように簡略化しています。コンパイル時に、ジェネリックメソッドまたはクラスへのすべての呼び出しは、基本的に完全に別のクラスとして生成されます。

タイプをベースにしてリフレクションを使用する方がずっと簡単です。これはどうにかする必要があります。

+0

True、Leeのメソッドは、MethodInfoを取得するための追加のリフレクションがメソッドで回避できる追加の計算であるため、パフォーマンスが向上します。 –

関連する問題