我没有参加 PDC 2008,但听说 C# 4.0 宣布支持泛型协变和逆变。即 List<string>
可以分配给List<object>
.怎么可能?
在 Jon Skeet 的书 C# in Depth 中,解释了为什么 C# 泛型不支持协变和逆变。它主要用于编写安全代码。现在,C# 4.0 更改为支持它们。会不会带来困惑?
谁知道C# 4.0的细节可以给些解释?
最佳答案
Variance 只会以安全的方式得到支持——事实上,使用 CLR 已有的能力。所以我在尝试使用 List<Banana>
的书中给出的示例作为 List<Fruit>
(或不管它是什么)仍然不起作用 - 但其他一些情况会起作用。
首先,它只支持接口(interface)和委托(delegate)。
其次,它要求接口(interface)/委托(delegate)的作者将类型参数修饰为in
。 (用于逆变)或 out
(协方差)。最明显的例子是 IEnumerable<T>
它只会让您从中“取出”值 - 它不会让您添加新值。那将变成IEnumerable<out T>
.这根本不会损害类型安全,但可以让您返回 IEnumerable<string>
来自声明返回 IEnumerable<object>
的方法例如。
逆变性很难给出使用接口(interface)的具体示例,但使用委托(delegate)很容易。考虑 Action<T>
- 这仅表示采用 T
的方法范围。能够使用 Action<object>
无缝转换会很好作为Action<string>
- 任何采用 object
的方法当它与 string
一起出现时,参数会很好反而。当然,C# 2 在某种程度上已经具有委托(delegate)的协变和逆变,但是通过从一种委托(delegate)类型到另一种委托(delegate)类型的实际转换(创建新实例)——参见 P141-144 的示例。 C# 4 将使它更通用,并且(我相信)将避免为转换创建新实例。 (这将是一个引用转换。)
希望这能让它更清楚一些 - 如果它没有意义,请告诉我!
关于c# - C# 4.0 中如何实现泛型协变和逆变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/245607/