C#语言将开放类型定义为类型参数或使用未知类型参数定义的泛型的类型:
所有类型都可以分为开放类型或封闭类型。一个 开放式 的,涉及类型参数的类型。进一步来说:
一个 封闭式 是一种类型,是不是开放类型。
因此T
,List<T>
和Dictionary<string,T>
和Dictionary<T,U>
都是开放类型(T
和U
是类型参数),而List<int>
和Dictionary<string,int>
是封闭类型。
有一个相关的概念: 未绑定的泛型类型 是带有未指定类型参数的泛型类型。非绑定类型不能用于除之外的表达式中,typeof()
并且您不能实例化它或调用其方法。例如,List<>
和Dictionary<,>
是未绑定的类型。
要澄清开放类型和未绑定类型之间的细微区别:
class Program {
static void Main() { Test<int>(); }
static void Test<T>() {
Console.WriteLine(typeof(List<T>)); // Print out the type name
}
}
如果您运行此代码段,它将打印出来
System.Collections.Generic.List`1[system.int32]
这是的CLR名称List<int>
。在运行时很明显type参数是system.int32
。这将成为List<T>
一个 绑定的 打开类型。
在运行时,你可以使用反射来绑定类型参数绑定的泛型类型与未指定的类型参数Type.MakeGenericType
的方法:
Type unboundGenericList = typeof(List<>);
Type listOfInt = unboundGenericList.MakeGenericType(typeof(int));
if (listOfInt == typeof(List<int>))
Console.WriteLine("Constructed a List<int> type.");
您可以检查类型是否是未绑定的泛型类型( 泛型类型定义 ),可以使用该Type.IsGenericTypeDefinition
属性从中构造绑定类型:
Console.WriteLine(typeof(Dictionary<,>).IsGenericTypeDeFinition); // True
Console.WriteLine(typeof(Dictionary<int,int>).IsGenericTypeDeFinition); // False
要在运行时从构造类型获取未绑定类型,可以使用Type.GetGenericTypeDefinition
方法。
Type listOfInt = typeof(List<int>);
Type list = listOfInt.GetGenericTypeDeFinition(); // == typeof(List<>)
请注意,对于泛型类型,您可以具有完全未绑定的类型定义或完全绑定的定义。您无法绑定某些类型参数,而使其他参数未绑定。例如,您不能拥有Dictionary<int,>
或Dictionary<,string>
。