我在第9频道观看了一段关于它的视频,但我对此并不是很了解。
有人可以给我一个关于这些容易理解的简单例子吗?那之后可能会如何在实践中使用它?
答案 0 :(得分:8)
你可能想看看这个博客,他在解释它方面做得非常出色,但我认为需要更多的例子来为人们清理它,因为这会进入一个非常难以理解的领域,但是,文章下面的引文总结得很好。
http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html
“协方差和逆变”是指 你现在可以传递不精确的泛型 如果这样做是安全的,就像这样 你可以传递不精确的参数类型 什么时候这样做是安全的。
答案 1 :(得分:7)
Tiger
是Animal
,因此它可以执行Animal
可以执行的任何操作。如果我有一个要求Animal
的方法,我也可以传入Tiger
。
协方差 - 传递更具体的类型参数
这是您最熟悉的方向。我可以在需要IEnumerable<Tiger>
的任何地方传递IEnumerable<Animal>
。
static void ListAnimals(IEnumerable<Animal> animals)
{
}
List<Tiger> tigers = new List<Tiger>();
ListAnimals(tigers);
Contravariance - 传递更一般的类型参数。
'contra'意味着这与正常的转换流程“相对”。这个比较棘手,因为它看起来反直觉,直到你看到它在行动。
假设我有一个功能,需要比较IComparer<Tiger>
和两只老虎。逆变法说我也可以传递更一般的IComparer<Animal>
,因为它可以也比较两只老虎(因为老虎是动物)。它以更一般的方式比较它们,但这仍然是类型安全的。
static void CompareTigers(IComparer<Tiger> comparer, Tiger tiger1, Tiger tiger2)
{
comparer.Compare(tiger1, tiger2);
}
// normal - a tiger comparer can compare two tigers
IComparer<Tiger> tigerComparer = null;
CompareTigers(tigerComparer, new Tiger(), new Tiger());
// contravariance - an animal comparer can ALSO compare two tigers
IComparer<Animal> animalComparer = null;
CompareTigers(animalComparer, new Tiger(), new Tiger());
请注意,这也适用于代表。我可以将Action<Animal>
传递给期望Action<Tiger>
的函数,因为Tiger
对象也可以安全地传递给Action<Animal>
代理。
答案 2 :(得分:3)
Eric Lippert在最近的blog post
中提出了一个非常好的解释答案 3 :(得分:1)
以下文章涉及与代表的共同和逆转:http://msdn.microsoft.com/en-us/library/ms173174.aspx。
即使你还没有进入代表,也许对你有用。我发现它很容易理解。
答案 4 :(得分:1)
C#4.0(和VB)的MSDN文档位于:Covariance and Contravariance
如果您对具体示例感兴趣,请访问: