.NET:协变和逆变
可能的重复:
协方差与协方差之间的差异逆变
我试图理解什么是协变和逆变,以及两者之间的区别。我查看了此链接,到目前为止我已经了解了以下:
协方差是将派生成员分配给基本成员的过程。如:
IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;
我什至不确定我上面的说法是否正确……猜测。基本上,我正在寻找有人用最简单的术语为我简化它,以便我能够理解两者是什么以及它们之间的区别。
我也知道有与此相关的类似讨论主题,但大多数答案都不是我想要的描述。
Possible Duplicate:
Difference between Covariance & Contra-variance
I'm trying to understand what covariance and contravariance is, as well as the difference between the two. I have looked at this link, and so far I have understood the following:
Covariance is the process by which you assign a derived member to a base member. Such as:
IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;
I'm not even sure if I am right in the above... guess. Basically I'm looking for someone to dumb it down for me, in the simplest of terms so that I can understand what the two are and the differences between them.
I also understand there are similar topics of discussion regarding this, but most of the answers aren't the kind of description I was looking for.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于我们的内部培训,我参考了精彩的书“Smalltalk、对象和设计(Chamond Liu)”,并重新表述了以下示例。 - 希望这会有所帮助...
“一致性”是什么意思?
这个想法是设计具有高度可替换类型的类型安全类型层次结构。获得这种一致性的关键是基于子类型的一致性。
(我们将在这里高层次地讨论里氏替换原理(LSP)。)
协方差:
让我们假设鸟类“一致”地使用静态类型来产蛋:
如果鸟这个类型会产蛋,那么鸟的亚型不会产蛋的亚型吗?
例如,Duck 类型产下 DuckEgg,然后给出一致性。
为什么这是一致的?因为在这样的表达中:
<代码>
鸡蛋 anEgg = aBird.Lay();
引用 aBird 可以合法地用 Bird 或 Duck 实例替换。
我们说返回类型与定义 Lay() 的类型是协变的。
子类型的覆盖可能会返回更专门的类型。 => “他们提供更多。”
逆变:
让我们假设钢琴家可以通过静态类型“一致”地演奏钢琴:
如果钢琴家弹钢琴,她能弹三角钢琴吗?
难道演奏家不愿意弹三角钢琴吗? (请注意;有一个转折!)这是不一致的!因为在这样的表达中:
<代码>
aPiano.Play(aPianist);
aPiano 不能合法地被 Piano 或 GrandPiano 实例替代!三角钢琴只有演奏家才能弹奏,钢琴家太一般了!
三角钢琴必须能够被更通用的类型演奏,这样演奏才能保持一致。
我们说参数类型与定义 Play() 的类型是逆变的。
子类型的覆盖可以接受更通用的类型。 => “他们需要的更少。”
For our internal trainings I have worked with the wonderful book "Smalltalk, Objects and Design (Chamond Liu)" and I rephrased following examples. - Hope this helps...
What does “consistency” mean?
The idea is to design type-safe type hierarchies with highly substitutable types. The key to get this consistency is sub type based conformance.
(We'll discuss the Liskov Substitution Principle (LSP) on a high level here.)
Covariance:
Let's assume Birds that lay Eggs “consistently” with static typing:
If the type Bird lays an Egg, wouldn't Bird's subtype lay a subtype of Egg?
E.g. the type Duck lays a DuckEgg, then the consistency is given.
Why is this consistent? Because in such an expression:
Egg anEgg = aBird.Lay();
the reference aBird could be legally substituted by a Bird or by a Duck instance.
We say the return type is covariant to the type, in which Lay() is defined.
A subtype's override may return a more specialized type. => “They deliver more.”
Contravariance:
Let's assume Pianos that Pianists can play “consistently” with static typing:
If a Pianist plays Piano, would she be able to play a GrandPiano?
Wouldn't rather a Virtuoso play a GrandPiano? (Be warned; there is a twist!) This is inconsistent! Because in such an expression:
aPiano.Play(aPianist);
aPiano couldn't be legally substituted by a Piano or by a GrandPiano instance! A GrandPiano can only be played by a Virtuoso, Pianists are too general!
GrandPianos must be playable by more general types, then the play is consistent.
We say the parameter type is contravariant to the type, in which Play() is defined.
A subtype's override may accept a more generalized type. => “They require less.”