ジェネリック型では、型引数に具体的な型が指定されているかどうかで型情報が変わります。 たとえばList<T>クラスを例にとった場合、型引数T
の型が具体的に定まっていないList<T>
を特にオープンジェネリック型(あるいはジェネリック型定義)、対してList<int>
やList<string>
など型引数T
の型が具体的な型が定まっているものをクローズジェネリック型(あるいは構築ジェネリック型、構築された型)と呼びます。
typeof
演算子・GetType
演算子でジェネリック型の型情報を取得する場合、オープンジェネリック型とクローズジェネリック型を区別して取得することができます。 オープンジェネリック型を表す場合は型パラメータの指定を省略した型名(例:Dictionary<,>
/Dictionary(Of ,)
)を使用し、一方クローズジェネリック型では具体的な型名を指定した型名(例:Dictionary<string, int>
/Dictionary(Of String, Integer)
)を使用することによってそれぞれの型情報を取得することができます。
オープンジェネリック型およびクローズジェネリック型の型情報を取得する
using System;
using System.Collections.Generic;
class Sample {
static void Main()
{
var t1 = typeof(List<>); // 型パラメータが1つのオープンジェネリック型
var t2 = typeof(List<int>); // 型パラメータが1つのクローズジェネリック型
var t3 = typeof(List<string>);
Console.WriteLine(t1);
Console.WriteLine(t2);
Console.WriteLine(t3);
var t4 = typeof(Dictionary<,>); // 型パラメータが2つのオープンジェネリック型
var t5 = typeof(Dictionary<string, int>); // 型パラメータが2つのクローズジェネリック型
Console.WriteLine(t4);
Console.WriteLine(t5);
var t6 = typeof(Action<,>);
var t7 = typeof(Action<,,>);
var t8 = typeof(Action<,,,>);
Console.WriteLine(t6);
Console.WriteLine(t7);
Console.WriteLine(t8);
}
}
実行結果
System.Collections.Generic.List`1[T] System.Collections.Generic.List`1[System.Int32] System.Collections.Generic.List`1[System.String] System.Collections.Generic.Dictionary`2[TKey,TValue] System.Collections.Generic.Dictionary`2[System.String,System.Int32] System.Action`2[T1,T2] System.Action`3[T1,T2,T3] System.Action`4[T1,T2,T3,T4]