这个问题已经在这里有一个答案:
- 泛型-开放和封闭的构造类型 3个回答
我所经历的Asp.Net MVC的教训和了解到,对于一个方法有资格作为控制器的动作,
- 它不能有一个“开放式泛型类型”
我明白有些仿制药,并用它们在一定程度上,但是:
- 什么是.NET中的开放式泛型类型 。
- 是否有这样的事,作为一个封闭泛型类型 ?
- 开放式泛型类型是不经常使用的术语。 是做什么用/与它混淆?
这个问题已经在这里有一个答案:
我所经历的Asp.Net MVC的教训和了解到,对于一个方法有资格作为控制器的动作,
我明白有些仿制药,并用它们在一定程度上,但是:
C#语言定义的开放式是一个类型,要么一个类型参数或未知类型的参数定义泛型类型:
所有类型都可归类为开放类型或封闭的类型。 开放式是涉及类型参数的类型。 进一步来说:
- A型参数定义的开放型。
- 数组类型是一个开放式当且仅当其元素类型是开放类型。
- 构造类型是开放型,当且仅当其类型参数中的一个或多个是开放类型 。 甲构造嵌套类型是开放型,当且仅当其类型参数或包含它的类型的类型参数中的一个或多个是开放类型。
在密闭型是一种类型,是不是开放类型。
因此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>
。 这是在运行时类型论点明确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>
。
我想补充:
Dictionary<string, T>
或更精确地Dictionary<string,>
)仍然是一个开放型。
例:
void Foo<T>(Dictionary<string,T> dic) { ... }
一个“开放的通用类型”只是目前还不具备它的类型指定了一个通用类型(例如, CargoCrate<T>
它成为“关闭”一次一个具体类型已经被分配(例如CargoCrate<Widget>
)。
例如,假设你有这样的事情:
public class Basket<T> {
T[] basketItems;
}
public class PicnicBlanket<T> {
Basket<T> picnicBasket; // Open type here. We don't know what T is.
}
// Closed type here: T is Food.
public class ParkPicnicBlanket : PicnicBlanket<Food> {
}
在这里, picnicBasket
的类型是开放的:什么也没有尚未分配给T
。 当你做一个具体的PicnicBlanket与特定类型-例如,通过写PicnicBlanket<Food> p = new PicnicBlanket<Food>()
-我们现在称之为封闭 。
有三种通用类型。 要长话短说,在此(简化)声明:
public class Dictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
Dictionary<TKey, TValue>
是无界的通用类型 。
KeyValuePair<TKey, TValue>
,在这种情况下, 开放式构造的通用类型 。 它有一些类型的参数,但它们已经别处定义(在词典,在这种情况下)。
Dictionary<string, int>
将是一个封闭构造的通用类型 。