【问题标题】:.NET: Covariance and Contravariance [duplicate].NET:协方差和逆变[重复]
【发布时间】:2011-07-10 20:17:59
【问题描述】:
可能重复:
Difference between Covariance & Contra-variance
我试图了解什么是协变和逆变,以及两者之间的区别。我看过this link,到目前为止我已经理解了以下内容:
协方差是将派生成员分配给基础成员的过程。如:
IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;
我什至不确定我在上面是否正确......猜猜。基本上,我正在寻找可以用最简单的术语为我简化它的人,以便我能够理解两者是什么以及它们之间的区别。
我也知道对此有类似的讨论主题,但大多数答案不是我想要的那种描述。
【问题讨论】:
标签:
.net
covariance
contravariance
【解决方案1】:
在我们的内部培训中,我使用了精彩的书籍“Smalltalk, Objects and Design (Chamond Liu)”,并改写了以下示例。 - 希望这会有所帮助...
“一致性”是什么意思?
这个想法是设计具有高度可替换类型的类型安全类型层次结构。获得这种一致性的关键是基于子类型的一致性。
(我们将在这里从高层次上讨论 Liskov 替换原则 (LSP)。)
协方差:
让我们假设鸟类使用静态类型“一致地”产卵:
如果鸟类型下蛋,那么鸟的子类型不会下蛋的子类型吗?
例如。 Duck 类型放置一个 DuckEgg,然后给出一致性。
为什么这是一致的?因为在这样的表达中:
Egg anEgg = aBird.Lay();
引用 aBird 可以合法地替换为 Bird 或 Duck 实例。
我们说返回类型与定义 Lay() 的类型是协变的。
子类型的覆盖可能会返回更特殊的类型。 => “他们提供更多。”
逆变:
让我们假设钢琴家可以使用静态类型“一致地”演奏钢琴:
如果钢琴家弹钢琴,她会弹钢琴吗?
不是更喜欢演奏家演奏三角钢琴吗? (警告;有一个转折!)这是不一致的!因为在这样的表达中:
aPiano.Play(aPianist);
aPiano 不能被 Piano 或 GrandPiano 实例合法替代! GrandPiano 只能由 Virtuoso 演奏,钢琴家太笼统了!
GrandPianos 必须能被更一般的类型演奏,然后演奏是一致的。
我们说参数类型与定义 Play() 的类型是逆变的。
子类型的覆盖可以接受更通用的类型。 => “他们需要的更少。”