WCFを利用したサービスのバックグラウンドで動いてもらうフレームワークを作成するときに必要だったので調べてみると、System.Type型のメソッドにMakeGenricTypeという、そのままのメソッドがあってこれで作成できる事がわかりました。
そこで、ここではList<int>型を作成し、1から10までの値をListに登録するサンプルコードを紹介したいと思います。
普段の実装でこのようなコメントを書くことはありませんがコメントで解説します。
//List<>の<>内に入れる型のメタデータの配列を生成します。
//今回はList<int>型を作成したいので、int型のメタデータを生成します。
System.Type[] genericsTypeArguments = { typeof(int) };
//List<>のメタデータのMakeGenricTypeメソッドに先ほど作成した
//int型のメタデータを渡すことでList<int>型のメタデータを作成できます。
//実は、これを知るまで<>という中に何も入れない書き方ができる事を知りませんでした。
System.Type integerListType = typeof(List<>).MakeGenericType(genericsTypeArguments);
//後は通常のメタデータからインスタンスを生成するように
//CreateInstanceでインスタンスを生成します。
var integerList = Activator.CreateInstance(integerListType);
//integerListはobject型であり、動的に作成するというシナリオ上、
//何のListになったのかわからないので、
//ListのAddメソッドの情報を取得します。
var addMethodInfo = integerListType.GetMethod("Add");
//addメソッドを利用するサンプルとして便宜的に1から10までの数と登録します。
foreach (var value in Enumerable.Range(1,10))
{
//Addメソッドの情報からInvokeメソッドを利用して、
//Addメソッドを実行し、与えられた値を設定します。
addMethodInfo.Invoke(integerList, new object[] { value });
}
以上が、ジェネリック型を動的に生成する方法です。
型の配列の要素を現在のジェネリック型定義の型パラメータで置き換え、結果の構築型を表す Type オブジェクトを返します。