The question is "what is the difference between covariance and contravariance?"
Covariance and contravariance are properties of mappings between sets.
Consider the following two sets of types:
{ Animal,
Tiger,
Fruit,
Banana }.
And this clearly related set:
{ IEnumerable<Animal>,
IEnumerable<Tiger>,
IEnumerable<Fruit>,
IEnumerable<Banana> }
There is a mapping from the first set to the second set. That is, for each T in the first set, the corresponding type in the second set is IEnumerable<T>
. Or, in short form, the mapping is T → IE<T>
.
With me so far?
There is an assignment compatibility relationship between pairs of types in the first set. A value of type Tiger can be assigned to a variable of type Animal. Let's write "a value of type X can be assigned to a variable of type Y" in a shorter form: X ⇒ Y
. So:
Tiger ⇒ Tiger
Tiger ⇒ Animal
Animal ⇒ Animal
Banana ⇒ Banana
Banana ⇒ Fruit
Fruit ⇒ Fruit
In C# 4 there is an assignment compatibility relationship between pairs of types in the second set.
IE<Tiger> ⇒ IE<Tiger>
IE<Tiger> ⇒ IE<Animal>
IE<Animal> ⇒ IE<Animal>
IE<Banana> ⇒ IE<Banana>
IE<Banana> ⇒ IE<Fruit>
IE<Fruit> ⇒ IE<Fruit>
Notice that the mapping T → IE<T>
preserves the existence and direction of assignment compatibility. That is, if X ⇒ Y
, then IE<X> ⇒ IE<Y>
.
A mapping which has this property is called a "covariant mapping".
Now consider the set
{ IComparable<Tiger>,
IComparable<Animal>,
IComparable<Fruit>,
IComparable<Banana> }
now we have the mapping from the first set to the third set T → IC<T>
.
In C# 4:
IC<Tiger> ⇒ IC<Tiger>
IC<Animal> ⇒ IC<Tiger> Backwards!
IC<Animal> ⇒ IC<Animal>
IC<Banana> ⇒ IC<Banana>
IC<Fruit> ⇒ IC<Banana> Backwards!
IC<Fruit> ⇒ IC<Fruit>
That is, the mapping T → IC<T>
has preserved the existence but reversed the direction of assignment compatibility. That is, if X ⇒ Y
, then IC<X> ⇐ IC<Y>
.
Such a mapping is called a contravariant mapping.
So that's the difference between covariance and contravariance. Covariance preserves the direction of assignability. Contravariance reverses it.