Alex Rivera | Logout

Contravariance explained

Asked 2009-12-26T04:48:17.540
44

First of, I have read many explanations on SO and blogs about covariance and contravariance and a big thanks goes out to Eric Lippert for producing such a great series on Covariance and Contravariance.

However I have a more specific question that I am trying to get my head around a little bit.

As far as I understand per Eric's explanation is that Covariance and Contravariance are both adjectives that describe a transformation. Covariant transformation is that which preserves the order of types and Contravariant transformation is one that reverses it.

I understand covariance in such a manner that I think most developers understand intuitively.

//covariant operation
Animal someAnimal = new Giraffe(); 
//assume returns Mammal, also covariant operation
someAnimal = Mammal.GetSomeMammal(); 

The return operation here is covariant as we are preserving the size in which both Animal is still bigger than Mammal or Giraffe. On that note most return operations are covariant, contravariant operations would not make sense.

  //if return operations were contravariant
  //the following would be illegal
  //as Mammal would need to be stored in something
  //equal to or less derived than Mammal
  //which would mean that Animal is now less than or equal than Mammal
  //therefore reversing the relationship
  Animal someAnimal =  Mammal.GetSomeMammal(); 

This piece of code of course would not make sense to most developers.

My confusion lies in Contravariant argument parameters. If you had a method such as

bool Compare(Mammal mammal1, Mammal mammal2);

Edit
Report

1 Answer

1

(Edited in response to comments)

This MSDN article on the topic described covariance and contravariance as it applies to matching a function to a delegate. A variable of the delegate type:

public delegate bool Compare(Giraffe giraffe, Dolphin dolphin);

could (because of contravariance) be populated with the function:

public bool Compare(Mammal mammal1, Mammal mammal2)
{
    return String.Compare(mammal1.Name, mammal2.Name) == 0;
}

From my reading, it doesn't have to do with calling the function directly, but matching functions with delegates. I'm not sure that it can be boiled down to the level you demonstrate, with individual variables or object assignments being contravariant or covariant. But the assignment of a delegate uses contravariance or covariance in a way that makes sense to me according to the linked article. Because the delegate's signature contains more derived types than the actual instance, this is referred to as "contravariance", something separate from "covariance" in which a delegate's return type is less derived than the actual instance.

answered 2009-12-26T13:56:05.030

Your Answer