我正在学习 Asp.Net MVC 课程,并且了解到一个方法要作为控制器的操作,需要满足以下条件:
- 它不能有“开放式泛型类型”
我对泛型有一定的了解并在某种程度上使用它们,但是:
- .Net 中的开放式泛型类型是什么?
- 是否存在封闭式泛型类型?
- 开放式泛型类型 不常使用这个术语,有哪些术语会被使用或混淆?
我正在学习 Asp.Net MVC 课程,并且了解到一个方法要作为控制器的操作,需要满足以下条件:
我对泛型有一定的了解并在某种程度上使用它们,但是:
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]
这是 List<int>
的CLR名称。在运行时,类型参数为 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
方法。请注意保留HTML标签。Type listOfInt = typeof(List<int>);
Type list = listOfInt.GetGenericTypeDefinition(); // == typeof(List<>)
Dictionary<int,>
或Dictionary<,string>
。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>()
-- 我们现在称其为 封闭的。
补充一点:
Dictionary<string, T>
(或更准确地说是Dictionary<string,>
)仍然是一个开放类型。
例如:
void Foo<T>(Dictionary<string,T> dic) { ... }
List<T>
定义为开放类型,而List<>
定义为未绑定类型。澄清我的答案。+1 - Mehrdad Afshari有三种泛型类型。简而言之,在这个(简化的)声明中:
public class Dictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
Dictionary<TKey, TValue>
是一个 无限制的泛型类型。
KeyValuePair<TKey, TValue>
在这种情况下是一个 开放构造的泛型类型。它具有一些类型参数,但它们已在其他地方(在本例中为 Dictionary)中定义。
Dictionary<string, int>
将是一个 封闭构造的泛型类型。
Dictionary<int,>
,实际上可以通过typeof(Dictionary<,>).MakeGenericType(typeof(int), typeof(Dictionary<,>).GetGenericArguments()[1])
来构造。但也许你只是想说C#不允许使用语法Dictionary<int,>
,所以我们必须像我在这里做的那样手动创建它。 - Jeppe Stig NielsenIsGenericType
的文档页面上,在示例部分的C#代码中,他们以更优雅的方式考虑了一个类型Base`2[System.String,V]
,其中一个类型参数被替换为具体类型,另一个类型参数被替换为参数V
。 - Jeppe Stig Nielsen