一般协方差是怎样的&;在C#4.0中实现的抵销差异?

一般协方差是怎样的&;在C#4.0中实现的抵销差异?,c#,c#-4.0,covariance,contravariance,generic-variance,C#,C# 4.0,Covariance,Contravariance,Generic Variance,我没有参加PDC2008,但我听到一些消息说C#4.0宣布支持通用协方差和反方差。也就是说,List可以分配给List。怎么可能呢 在Jon Skeet的书《C#Depth》中,解释了为什么C#泛型不支持协方差和反方差。它主要用于编写安全代码。现在,C#4.0已经改变以支持它们。它会带来混乱吗 任何了解C#4.0细节的人都可以给出一些解释?只有在安全的方式下才能支持差异-事实上,使用CLR已经具备的功能。因此,我在书中给出的尝试将列表用作列表(或其他任何内容)的示例仍然不起作用,但其他一些场景会

我没有参加PDC2008,但我听到一些消息说C#4.0宣布支持通用协方差和反方差。也就是说,
List
可以分配给
List
。怎么可能呢

在Jon Skeet的书《C#Depth》中,解释了为什么C#泛型不支持协方差和反方差。它主要用于编写安全代码。现在,C#4.0已经改变以支持它们。它会带来混乱吗


任何了解C#4.0细节的人都可以给出一些解释?

只有在安全的方式下才能支持差异-事实上,使用CLR已经具备的功能。因此,我在书中给出的尝试将
列表
用作
列表
(或其他任何内容)的示例仍然不起作用,但其他一些场景会起作用

首先,它只支持接口和代理

其次,它要求接口/委托的作者将类型参数修饰为
in
(对于协方差)或
out
(对于协方差)。最明显的例子是
IEnumerable
,它只允许您从中“取出”值,而不允许您添加新值。这将成为
IEnumerable
。这根本不会影响类型安全性,但允许您从声明为返回
IEnumerable
的方法返回
IEnumerable

相反,很难给出使用接口的具体示例,但使用委托很容易。考虑<代码> Actudio,它只代表一个方法,它采用了<代码> t>代码>参数。如果能够无缝地将
动作
转换为
动作
,那就太好了——任何采用
对象
参数的方法,只要用
字符串
来表示,都是可以的。当然,C#2在某种程度上已经具有委托的协方差和逆变,但是通过从一种委托类型到另一种委托类型的实际转换(创建一个新实例)——参见第141-144页的示例。C#4将使这更通用,并且(我相信)将避免为转换创建新实例。(它将改为引用转换。)


希望这能澄清一点-如果没有意义,请让我知道

并不是说Jon还没有报道,而是这里有一些链接,指向Eric Lippert的博客和视频。他用例子很好地解释了这一点

视频:


那么,这是否意味着如果类被声明为“List”,那么它就不应该有像“void Add(T obj)”这样的成员函数?C#4.0编译器会报告这方面的错误,对吗?摩根:这当然是我的理解,是的。你在这里的一个答案立即帮助我改进了一些代码。谢谢大家!@阿肯:是的,我知道。因此,同一句中的“仍然不起作用”。(我也知道其中的原因。)@JonSkeet如@Ark kun所说,“你只能将
列表
用作
IList
”是否正确?如果是这样的话,这是怎么可能的,尽管接口的类型参数没有定义为协变的(没有
out T
,而只是
T
),自从.NET2.0以来,它已经在IL中得到了支持。