Contravariance reverses the assignment direction associated with a type relationship. If a Giraffe is an Animal, an interface that accepts Animals can be used where an interface accepting Giraffes is expected: it already handles every Giraffe. section 7.3
abstract class Animal : Object {}
class Giraffe : Animal {}
class Tiger : Animal {}
interface IC<in T>
{
int CompareTo(T item1, T item2);
}
The C# interface marks its type parameter with `in`, documenting that T appears only in input positions. section 7.3
Animal comparer assigned as a giraffe comparer
An IC<Animal> can be assigned to an IC<Giraffe>. The comparer promises to compare any two Animals, so it can safely accept two Giraffes. The apparently backward conversion is the defining surprise: the type argument moves from Giraffe to Animal while the interface relationship points in the opposite direction. section 7.3
Viewed categorically, types are objects and assignment compatibility is a morphism. Mapping T to IC<T> preserves those morphisms while reversing their direction, making IC<T> a contravariant endofunctor. section 7.3 section 7.4

