我正在学习Asp.Net MVC课程,并了解到,对于一种有资格作为控制器动作的方法,
我对泛型有些了解,并在一定程度上使用了它们,但是:
C#语言将开放类型定义为类型参数或使用未知类型参数定义的泛型的类型:
所有类型都可以分为开放类型或封闭类型。一个 开放式 的,涉及类型参数的类型。进一步来说: 类型参数定义一个开放类型。 且仅当其元素类型为开放类型时,数组类型才为开放类型。 甲 构造类型 是开放型,当且仅当其类型参数中的一个或多个是一个 开放型 。甲 构造嵌套类型 是开放型,当且仅当一个或多个其类型参数或包含它的类型的类型参数是一个开放型。 一个 封闭式 是一种类型,是不是开放类型。
所有类型都可以分为开放类型或封闭类型。一个 开放式 的,涉及类型参数的类型。进一步来说:
一个 封闭式 是一种类型,是不是开放类型。
因此T,List<T>和Dictionary<string,T>和Dictionary<T,U>都是开放类型(T和U是类型参数),而List<int>和Dictionary<string,int>是封闭类型。
T
List<T>
Dictionary<string,T>
Dictionary<T,U>
U
List<int>
Dictionary<string,int>
有一个相关的概念: 未绑定的泛型类型 是带有未指定类型参数的泛型类型。非绑定类型不能用于除之外的表达式中,typeof()并且您不能实例化它或调用其方法。例如,List<>和Dictionary<,>是未绑定的类型。
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>一个 绑定的 打开类型。
System.Int32
在运行时,你可以使用反射来绑定类型参数绑定的泛型类型与未指定的类型参数Type.MakeGenericType的方法:
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属性从中构造绑定类型:
Type.IsGenericTypeDefinition
Console.WriteLine(typeof(Dictionary<,>).IsGenericTypeDefinition); // True Console.WriteLine(typeof(Dictionary<int,int>).IsGenericTypeDefinition); // False
要在运行时从构造类型获取未绑定类型,可以使用Type.GetGenericTypeDefinition方法。
Type.GetGenericTypeDefinition
Type listOfInt = typeof(List<int>); Type list = listOfInt.GetGenericTypeDefinition(); // == typeof(List<>)
请注意,对于泛型类型,您可以具有完全未绑定的类型定义或完全绑定的定义。您无法绑定某些类型参数,而使其他参数未绑定。例如,您不能拥有Dictionary<int,>或Dictionary<,string>。
Dictionary<int,>
Dictionary<,string>