理解C#4.0中的协方差和逆变

我在第9频道观看了一段关于它的video,但我对此并不是很了解。

有人可以给我一个关于这些容易理解的简单例子吗? 之后可能会如何在实践中使用它?

你可能想看看这个博客,他在解释它方面做得非常出色,但我认为需要更多的例子来为人们清理它,因为这会进入一个非常难以理解的领域,但是,引用以下文章总结得很好。

http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html

“协方差和逆变”意味着您现在可以在安全的情况下传递不精确的generics类型,就像您可以安全地传递不精确的参数类型一样。

Tiger是一种Animal所以它可以做Animal可以做的任何事情。 如果我有一个要求Animal的方法,我也可以通过Tiger

协方差 – 传递更具体的类型参数

这是您最熟悉的方向。 我可以在任何需要IEnumerable地方传递IEnumerable IEnumerable


 static void ListAnimals(IEnumerable animals) { } List tigers = new List(); ListAnimals(tigers); 

逆变 – 传递更一般的类型参数。

‘contra’意味着这与正常的转换流程“相反”。 这个比较棘手,因为它看起来反直觉,直到你看到它在行动。

假设我有一个function,期望IComparer和两只老虎进行比较。 逆变法说我也可以传递更一般的IComparer因为它也可以比较两只老虎(因为老虎是动物)。 它以更一般的方式比较它们,但这仍然是类型安全的。


 static void CompareTigers(IComparer comparer, Tiger tiger1, Tiger tiger2) { comparer.Compare(tiger1, tiger2); } // normal - a tiger comparer can compare two tigers IComparer tigerComparer = null; CompareTigers(tigerComparer, new Tiger(), new Tiger()); // contravariance - an animal comparer can ALSO compare two tigers IComparer animalComparer = null; CompareTigers(animalComparer, new Tiger(), new Tiger()); 

请注意,这也适用于代表。 我可以将Action传递给期望Action的函数,因为Tiger对象也可以安全地传递给Action委托。

Eric Lippert在最近的博客文章中提出了一个非常好的解释

以下文章涉及与代表的共同和逆转: http : //msdn.microsoft.com/en-us/library/ms173174.aspx 。

也许它对你有用,即使你还没有进入代表。 我发现它很容易理解。

C#4.0(和VB)的MSDN文档在这里: 协方差和逆变

如果您对具体示例感兴趣,请访问:

  • 在通用集合的接口中使用方差

  • 在代表中使用差异

  • 对Func和Action Generic代表使用Variance