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

Joa*_*nge 17 .net c# covariance contravariance

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

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

Jam*_*ack 8

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

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

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


Des*_*tar 7

一个TigerIS是一个Animal可以做任何Animal可以做的事情.如果我有一个方法要求Animal我也可以传入一个Tiger.

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

这是您最熟悉的方向.我可以通过IEnumerable<Tiger>任何期望的地方IEnumerable<Animal>.


static void ListAnimals(IEnumerable<Animal> animals)
{
}

List<Tiger> tigers = new List<Tiger>();
ListAnimals(tigers);
Run Code Online (Sandbox Code Playgroud)

逆变 - 传递更一般的类型参数.

'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());
Run Code Online (Sandbox Code Playgroud)

请注意,这也适用于代表.我可以将Action<Animal>一个函数传递给一个函数,该函数需要一个Action<Tiger>因为Tiger对象也可以安全地传递给Action<Animal>委托.