いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

ジェネリックな型を動的に作成する(Type, Activator, Generic)

.NETで動的にインスタンスを作成するには、

Type type = Type.GetType("System.Collections.ArrayList");

IList list = Activator.CreateInstance(type) as IList;

のようにしますが、.NET 2.0からはジェネリック(System.Collections.Generic)型が
追加されています。


ジェネリック型の場合は、型引数が存在するので上記のように

Type type = Type.GetType("System.Collections.Generic.List");

としても失敗します。正確には、typeがnullで返ってきます。


ジェネリックインスタンスを動的に作成するには、GetTypeに渡す
文字列を以下のようにします。

型名`型引数の個数[型引数の型......(複数の場合はカンマで区切る)]


以下、サンプルです。

//
// ジェネリック型であるSystem.Collection.Generic.Listオブジェクトを動的に作成.
// 型引数は、stringとする。
//
// [補足]
// Type.GetTypeにて、ジェネリックな型を生成するには以下のような書式で行う.
//
//      型名`型引数の個数[型引数の型......(複数の場合はカンマで区切る)]
//
// たとえば、型引数を2つとるDictionaryの場合は、
//
//      System.Collections.Generic.Dictionary`2[System.String, System.Type]
//
// のようになる。
// また、これは以下の場合と同じとなる。
//
//      typeof(Dictionary<string, Type>)
//
Type t = Type.GetType("System.Collections.Generic.List`1[System.String]");

List<string> li = Activator.CreateInstance(t) as List<string>;
li.AddRange(new string[]{"hoge", "hehe"});
li.ForEach(delegate(string v){
    Console.WriteLine(v);
});

本当は、作成したTypeからインスタンスを作りobject型のままで
リフレクションを利用して動的にメソッドなどを呼び出すべきですが
サンプルなのでやめました。

System.TypeのAPIドキュメントには、このほかにもいろいろな形での
インスタンス作成書式が記述されています。
配列の場合は、"型名[]"として記述したりします。


================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。