2007-06-12

Animals and Baboons explained

I have been doing some research on the Animal/Baboon generic issue.
First I posted a feedback on the Microsoft connect site and got some answers. This issue is referred as covariance.
Covariance, in a mathematical definition, refers to how much two random variables varies together.
Covariance, in this aspect, refers to on how you can assign two variables/types to each other. Normally (without covariance) we can only assign objects to variables that are part of their inheritance chain or cast up the inheritance chain.
For instance
AccessViolationException ax = new AccessViolationException();
//assign down the inheritance chain
Exception ex = ax;
//cast up the inheritance chain
ax = ex as AccessViolationException;
We can also cast/assign to other types, but then it is up to the object to handle the cast/assignment by implementing the explicit or implicit operators for each type that it should support.

When it comes to covariance, this is already implemented in the CLR and C# (like Java) uses covariance for its support on Arrays.
To illustrate this we can use our Animal/Baboon/List<T> example.
List<Animal> myAnimalList;
List<Baboon> myBaboonList;
myAnimalList = myBaboonList; //gives a compiler error
The code above gererated a compiler error since we cannot convert the Baboon List to an Animal List. Baboon inherits Animal but List<Baboon> does not inherit List<Animal> and thus cannot be assigned to each others. But what happens if we do the same with arrays?
Baboon[] myBaboons = null;
Animal[] myAnimals;
myAnimals = myBaboons; //this works!?
How is this possible? Baboon[] does not inherit Animal[]. All arrays inherits System.Array.
This is because System.Array uses Covariance in the CLR to allow such a structure. Observe that the opposite is not possible
myBaboons = myAnimals; //gives a compiler error

This is called Contravariant and is not used by Arrays.

For now there is no other object or class that uses co/contra-variance in C# but since the feature is included in the CLI, you could build an own C# compiler that supports it.
Microsoft will not include the support in C# v3 but according to Mads Torgersen they are "actively looking at supporting it in the next version of the language after that".
If you would like more reading on the subject, I can recommend the following sources that have given me much input.

No comments:

Post a Comment