c# - C# 4.0 中如何实现泛型协变和逆变?

标签 c# c#-4.0 covariance contravariance generic-variance

我没有参加 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/

相关文章:

asp.net - 我应该多久打开/关闭一次 Booksleeve 连接?

java - Kotlin:泛型和方差

java - 获取 BufferedImage 的每像素位数

c#-4.0 - EF 代码优先 - Include(x => x.Properties.Entity) a 1 : Many association

C# AD 用户密码过期

c# - 将 List<DerivedClass> 转换为 List<BaseClass>

c# - 显示模态时如何最小化所有者窗口?

c# - wkhtmltopdf 不会在 html 文件中拍摄图像

c# - 为什么在 c# 中不能将可空的 int 作为字符串为 null?

c# - 具有多泛型问题的 AppDomain.DoCallBack()