我没有参加PDC 2008,但是我听到一些消息,宣布C#4.0支持通用协方差和反方差。即List<string>
可以分配给List<object>
。怎么可能
在乔恩·斯基特(Jon Skeet)的《C#in Depth》一书中,解释了为什么C#泛型不支持协方差和逆方差。它主要用于编写安全代码。现在,C#4.0更改为支持它们。会带来混乱吗?
有人知道有关C#4.0的详细信息可以给出一些解释吗?
我没有参加PDC 2008,但是我听到一些消息,宣布C#4.0支持通用协方差和反方差。即List<string>
可以分配给List<object>
。怎么可能
在乔恩·斯基特(Jon Skeet)的《C#in Depth》一书中,解释了为什么C#泛型不支持协方差和逆方差。它主要用于编写安全代码。现在,C#4.0更改为支持它们。会带来混乱吗?
有人知道有关C#4.0的详细信息可以给出一些解释吗?
Answers:
仅以安全的方式支持方差-实际上,使用CLR已具备的功能。因此,我在本书中尝试使用a List<Banana>
作为List<Fruit>
(或其他形式)的示例仍然无法使用-但其他一些情况也可以。
首先,只支持接口和委托。
其次,它要求接口/委托的作者将类型参数修饰in
为out
(对于协方差)或(对于协方差)。最明显的例子是IEnumerable<T>
,仅允许您从中“取出”值-不允许添加新值。那将成为IEnumerable<out T>
。这根本不会损害类型安全,但是可以让您IEnumerable<string>
从声明为要返回的方法中返回IEnumerable<object>
。
协方差很难给出使用接口的具体示例,但是使用委托很容易。考虑Action<T>
-仅代表采用T
参数的方法。能够无缝转换Action<object>
为as 会很好Action<string>
-任何带有object
参数的方法在显示a时都会很好string
。当然,C#2在某种程度上已经具有委托的协方差和相反性,但是通过从一种委托类型到另一种委托类型的实际转换(创建新实例),请参见P141-144。C#4将使其变得更通用,并且(我相信)将避免为转换创建新实例。(这将是参考转换。)
希望这能解决问题-如果没有任何意义,请通知我!
List<Banana>
如IList<Fruit>
“ @ Ark-kun”所说,“您只能将a 用作” 是正确的吗?如果是这样,那怎么可能,尽管IList<T>
接口的类型参数未定义为协变(no out T
,只是简单地T
)。
乔恩(Jon)尚未介绍过它,但是这里有一些指向埃里克·利珀特(Eric Lippert)博客和视频的链接。他通过示例很好地解释了这一点。
https://blogs.msdn.microsoft.com/ericlippert/2007/10/16/covariance-and-contravariance-in-c-part-one/
视频:
https://www.youtube.com/watch?v=3MQDrKbzvqU