2009-11-12 65 views
17

我在Channel 9上观看了一段关于它的视频,但我并没有真正理解它。了解C#4.0中的协变和反变化

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

+2

什么是Channel 9? – 2009-11-12 19:55:27

+2

http://channel9.msdn.com/ - 有关微软开发框架的视频集合,以及更多:) – cwap 2009-11-12 19:56:59

+0

是啊,它就像一个播客,有一些非常好的安德斯等C#视频等。 – 2009-11-12 19:58:48

回答

8

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

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

“协变和逆变”是指 您现在可以通过不精确通用 类型时,它是安全的这样做,就像 可以传递不准确的参数类型 当它是安全的这样做。

3

埃里克利珀一个很好的解释在最近blog post

7

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

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

这是你最熟悉的方向。我可以在任何需要IEnumerable<Animal>的地方通过IEnumerable<Tiger>


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()); 

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