我在第 9 频道观看了有关它的视频,但我并没有真正理解它。
有人可以给我一个简单易懂的例子吗?在那之后,它可能会如何在实践中使用?
我在第 9 频道观看了有关它的视频,但我并没有真正理解它。
有人可以给我一个简单易懂的例子吗?在那之后,它可能会如何在实践中使用?
你可能想看看这个博客,他解释得很好,但我认为需要更多的例子来为人们澄清它,因为这进入了一个非常难以理解的领域,但是,引用下面的文章总结得很好。
http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html
“协变和逆变”意味着您现在可以在安全的情况下传递不精确的泛型类型,就像在安全的情况下可以传递不精确的参数类型一样。
A Tiger
IS anAnimal
所以它可以做任何Animal
可以做的事情。如果我有一个要求 a 的方法,Animal
我也可以传入 a Tiger
。
协方差- 传递更具体的类型参数
这是你最熟悉的方向。我可以通过IEnumerable<Tiger>
任何需要IEnumerable<Animal>
.
static void ListAnimals(IEnumerable<Animal> animals)
{
}
List<Tiger> tigers = new List<Tiger>();
ListAnimals(tigers);
逆变- 传递更通用的类型参数。
“对立”意味着这与正常的转换流程“背道而驰”。这个比较棘手,因为在你看到它之前它似乎是反直觉的。
假设我有一个函数需要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());
请注意,这也适用于代表。我可以将 an 传递给Action<Animal>
一个期望 an 的函数,Action<Tiger>
因为Tiger
对象也可以安全地传递给Action<Animal>
委托。
Eric Lippert 在最近的一篇博文中提出了一个很好的解释
以下文章处理与代表的协变和逆变:http: //msdn.microsoft.com/en-us/library/ms173174.aspx。
也许它对你有用,即使你还没有进入代理。我发现它很容易理解。
C# 4.0(和 VB)的 MSDN 文档在这里:协方差和逆变
如果您对具体示例感兴趣,它们在这里: