6

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.

Community
  • 1
  • 1
Nahydrin
  • 13,197
  • 12
  • 59
  • 101

1 Answers1

0

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.”

Nico
  • 1,554
  • 1
  • 23
  • 35