我试图了解协方差和逆变是什么,以及两者之间的差异。我看过this link,到目前为止我已经理解了以下内容:
协方差是将派生成员分配给基本成员的过程。如:
IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;
我甚至不确定我是否在上面......猜猜。基本上我正在寻找一个让我愚蠢的人,用最简单的术语让我能理解这两者是什么以及它们之间的区别。
我也理解有相关的讨论主题,但大部分答案都不是我想要的那种描述。
答案 0 :(得分:0)
对于我们的内部培训,我使用了精彩的书“Smalltalk,Objects and Design(Chamond Liu)”,并重述了以下示例。 - 希望这会有所帮助...
“一致性”是什么意思? 我们的想法是设计具有高度可替换类型的类型安全类型层次结构。获得这种一致性的关键是基于子类型的一致性。 (我们将在这里高层讨论Liskov替换原则(LSP)。)
协方差:
让我们假设那些用“静态”打字“持续”产卵的鸟类:
如果Bird放置一个蛋类型,那么Bird的子类型不会产生蛋的子类型吗?
例如。 Duck类型放置DuckEgg,然后给出一致性。
为什么这一致?因为在这样的表达中:
Egg anEgg = aBird.Lay();
参考aBird可以由Bird或Duck实例合法替代。
我们说返回类型与类型协变,其中定义了Lay()。
子类型的覆盖可以返回更专用的类型。 =&GT; “他们提供更多。”
逆变:
让我们假设钢琴家可以“一致地”玩静态打字的钢琴:
如果钢琴家演奏钢琴,她能演奏GrandPiano吗?
是不是宁愿Virtuoso演奏GrandPiano? (警告;有一个扭曲!)这是不一致的!因为在这样的表达中:
aPiano.Play(aPianist);
aPiano不能被钢琴或GrandPiano实例合法取代! GrandPiano只能由Virtuoso演奏,钢琴家太一般了!
GrandPianos必须可以通过更一般的类型播放,然后播放是一致的。
我们说参数类型与类型是逆变的,其中定义了Play()。
子类型的覆盖可以接受更通用的类型。 =&GT; “他们需要更少。”