トップ回答者
ジェネリックスメソッドの型パラメータにDictionaryで保持しているTypeを指定する方法

質問
-
お世話になります。
ジェネリックスメソッドをループ処理で呼ぶ際の型パラメータに、
Dictionaryで保持しているTypeを使用したいのですが、可能でしょうか。以下、サンプルコードです。
=========================================================================
public class MainClass
{
//ジェネリックスメソッド
public T[] TestMethod<T>() where T : base1, new()
{
var rtn = new T[1];return rtn;
}
}//基本クラス
public class base1
{
//処理省略
}// 派生クラスA
public class ClassA:base1
{
//処理省略
}// 派生クラスB
public class ClassB:base1
{
//処理省略
}//-----実際の処理部分-----
class TestClass
{
void Test()
{
Dictionary<int, Type> ActDataKindCom = new Dictionary<int, Type>();
ActDataKindCom.Add(1,typeof(ClassA));
ActDataKindCom.Add(2,typeof(ClassB));for (int i = 1; i < 3; i++)
{
Type type = ActDataKindCom[i];
MainClass.TestMethod<type>();
}
}
}=========================================================================
上記のように、ディクショナリに型を保持しておいて、
ジェネリックスメソッドの型パラメータに使用したいのですが、
以下のようなエラーになります。型または名前空間名 'type' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。
このような場合、ループしないで1個ずつメソッド呼び出し処理を書くしかないのでしょうか?
回答
-
TestMethod<type>の記述ができたとして、そのtypeがbase1クラスから派生してるか、new()を持っているかはコンパイル時に決定できませんよね。
Dictionary<int, Action>
として、
ActDataKindCom.Add(1, () => MainClass.TestMethod<ClassA>());
のようにデリゲートを登録し(ラムダ式なのはTestMethod<T>がT[]を返すのでActionにできないため)、
ActDataKindCom[i]();
と呼び出す方法は考えられます。
- 回答としてマーク yurubon 2013年5月1日 7:06
すべての返信
-
TestMethod<type>の記述ができたとして、そのtypeがbase1クラスから派生してるか、new()を持っているかはコンパイル時に決定できませんよね。
Dictionary<int, Action>
として、
ActDataKindCom.Add(1, () => MainClass.TestMethod<ClassA>());
のようにデリゲートを登録し(ラムダ式なのはTestMethod<T>がT[]を返すのでActionにできないため)、
ActDataKindCom[i]();
と呼び出す方法は考えられます。
- 回答としてマーク yurubon 2013年5月1日 7:06
-
Hongliang様
早速のご回答有難うございます。
教えていただたいた通り、Actionにする事で、希望のメソッドを実行する事が出来ました。
さらに質問になって申し訳ないのですが、
Actionで実行したメソッドのリターン値を取得するにはどうしたら良いのでしょうか・・・?var a = ActDataKindCom[i]();
のように書いてもエラーになってしまい・・・。
(私のサンプルソースが戻り値を取得しないソースになっていて、申し訳ありません。)
佐祐理様
なるほど、納得しました。Typeも変数になってしまうのですね。
今回はすでにdllとして作られているメソッドを呼び出す方法を探していたので
Hongliang様の方法を使わせて頂く事にしましたが、
とても勉強になりました。有難うございました。