一尘不染

.NET中的“开放通用类型”到底是什么?[重复]

c#

我正在学习Asp.Net
MVC课程,
并了解到,对于一种有资格作为控制器动作的方法,

  • 它不能具有 “开放通用类型”

我对泛型有些了解,并在一定程度上使用了它们,但是:

  • 什么是.Net中的 开放通用类型
  • 封闭的泛型类型 吗?
  • 开放通用类型 是一个不经常使用的术语。有什么用/与它混淆?

阅读 327

收藏
2020-05-19

共1个答案

一尘不染

C#语言将开放类型定义为类型参数或使用未知类型参数定义的泛型的类型:

所有类型都可以分为开放类型或封闭类型。一个 开放式 的,涉及类型参数的类型。进一步来说:

  • 类型参数定义一个开放类型。
  • 且仅当其元素类型为开放类型时,数组类型才为开放类型。
  • 构造类型 是开放型,当且仅当其类型参数中的一个或多个是一个 开放型 。甲 构造嵌套类型
    是开放型,当且仅当一个或多个其类型参数或包含它的类型的类型参数是一个开放型。

一个 封闭式 是一种类型,是不是开放类型。

因此TList<T>Dictionary<string,T>Dictionary<T,U>都是开放类型(TU是类型参数),而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>

2020-05-19