6

可能的重复:
协方差和反方差之间的差异

我试图了解什么是协变和逆变,以及两者之间的区别。我看过这个链接,到目前为止我已经理解了以下内容:

协方差是将派生成员分配给基成员的过程。如:

IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;

我什至不确定我在上面是否正确......猜猜。基本上,我正在寻找可以用最简单的术语为我简化它的人,以便我可以理解两者是什么以及它们之间的区别。

我也知道对此有类似的讨论主题,但大多数答案都不是我正在寻找的那种描述。

4

1 回答 1

0

在我们的内部培训中,我使用了精彩的书籍“Smalltalk, Objects and Design (Chamond Liu)”,并重新表述了以下示例。- 希望这可以帮助...

“一致性”是什么意思?这个想法是设计具有高度可替换类型的类型安全类型层次结构。获得这种一致性的关键是基于子类型的一致性。(我们将在这里从高层次讨论 Liskov 替换原则 (LSP)。)

协方差:让我们假设 Birds 使用静态类型“一致地”产蛋:如果类型 Bird 产蛋,Bird 的子类型不会产蛋的子类型吗?例如 Duck 类型放置一个 DuckEgg,然后给出一致性。为什么这是一致的?因为在这样的表达式中: Egg anEgg = aBird.Lay(); 引用 aBird 可以合法地被 Bird 或 Duck 实例替换。我们说返回类型与定义 Lay() 的类型是协变的。子类型的覆盖可能会返回更特殊的类型。=> “他们提供更多。”</p>

逆变:让我们假设钢琴家可以通过静态类型“一致地”演奏钢琴:如果钢琴家演奏钢琴,她能演奏三角钢琴吗?不是更喜欢演奏家演奏三角钢琴吗?(警告;有一个转折!)这是不一致的!因为在这样的表达方式中: aPiano.Play(aPianist); aPiano 不能被 Piano 或 GrandPiano 实例合法地替代!GrandPiano 只能由 Virtuoso 演奏,钢琴家太笼统了!GrandPianos 必须能被更一般的类型演奏,然后演奏是一致的。我们说参数类型与定义 Play() 的类型是逆变的。子类型的覆盖可以接受更通用的类型。=> “他们需要的更少。”</p>

于 2011-07-10T20:30:11.447 回答