泛型开放和封闭构造类型

65

最近我注意到通用构造类型可以是开放和关闭的。但我不明白它们实际上意味着什么。你能给一个简单的例子吗?

3个回答

89
实际上,术语并不太重要 - 除了在尝试写它时,我几乎想不起上次担心它是什么意思了。
  • 未绑定类型没有指定类型参数
  • 构造类型至少有一个指定的类型参数
  • 类型参数是一个开放类型
  • 元素类型为开放类型的数组类型是一个开放类型
  • 开放构造类型至少有一个类型参数是开放类型
  • 闭合类型是任何不是开放类型的类型

(对于嵌套类型还有进一步的规则。请参阅C# 3.0规范第4.4节以获取详细信息。)

作为开放构造类型的示例,请考虑:

public class NameDictionary<T> : Dictionary<string, T>
typeof(NameDictionary<>) 的基类是:
  • 构建,因为它指定了类型参数
  • 开放,因为第二个类型参数 (T) 是一个开放类型
Type.IsGenericType 的 MSDN 文档有一个非常有用的表格。
再次强调,在日常使用中,这几乎完全不重要。
一般来说,我支持了解正确的术语 - 尤其是像“按引用传递”之类的东西 - 但在这种情况下,它真的很少出现。我希望积极阻止您担心它 :)

17
如果有人在面试中问我这个问题,我会坦白承认我不知道答案,除非查看书籍或规范文档 :) 我必须说,这不是一个很有用的面试问题。 - Jon Skeet
1
给我一部分你的大脑,这样我就能像Jon Skeet一样回答问题了。(开玩笑的,请原谅..) - user196546
1
因此,总结一下:如果我们发现任何类型参数,则它是一个限定/构造类型(否则它是未限定的),如果我们发现任何类型参数,则它是一个开放类型(否则它是封闭的)。封闭类型不能是未限定的。我有没有漏掉什么重要的? - explorer
3
@Jon ... 哈哈... 那实际上是一个很好的回答。我读得越多,就越觉得它们从一开始就不是为了人类消费而设计的。 - explorer
@JonSkeet,你会如何描述 List<>List<int> 之间的关系?后者是前者的封闭子类型吗?还是封闭版本?或者是封闭类型? - Ethan Reesor
显示剩余12条评论

10

来自MSDN

如果可实例化类型已替换为其所有类型参数,包括所有封闭类型的所有类型参数,则泛型类型或方法将关闭。 只有在关闭泛型类型时才能创建其实例。

因此,这个例子中的List<int>关闭的

var list = Activator.CreateInstance(typeof(List<int>));

但是运行时会抛出异常,因为 List<>开放的

var list = Activator.CreateInstance(typeof(List<>));
                                               ↑

2
在这种情况下,它也是一个未绑定的类型 - 开放的、构造的类型是更加神秘的一种 :) - Jon Skeet

3

我在依赖注入映射中主要使用了开放式泛型(即未实例化的泛型)。例如,像这样的东西:

Bind<IRepository<>>()
   .To<BasicRepository<>>()

接下来,当我的对象构造函数包含:

public SomethingController(IRepository<Something>) { ... }

我的依赖注入机制会自动实例化一个 BasicRepository< Something >。(这适用于 Ninject 和 StructureMap,可能也适用于 Castle Windsor 库;其他框架我不确定)。


Autofac 还支持开放式泛型类型:Autofac - 创建组件 - sgnsajgon
就像 SimpleInjector 一样 - Nick Jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接