Co-variant array conversions

Here’s one of my favorite programming questions: let’s say, in a C# program, we have a parent class

class Book
{
	public void Read() { Console.WriteLine("Reading..."); }
}

and a child class

class EBook : Book
{
    public void Download() {  Console.WriteLine("Downloading... "); }
}

In other words, EBook is a Book (a more special one - it can be downloaded).

Will the following code compile or not?

EBook[] eBooks = new EBook[10];
Book[] books = eBooks;  

I like this question, because when I heard it first, I went through the following thinking process:

  • Since an EBook is a Book, we should be able to use it wherever only a Book is required. We can always provide the more special type. So, probably the answer is “yes”.

  • However, although an EBook is a Book, that doesn’t automatically mean that an array of EBooks is an array of Books. In fact, there’s a problem with that: if the compiler will accept the conversion above, one could do this next:

books[0] = new Book()

Whoops - now we’ve inserted a new element into the array which is just a Book, not an eBook. So, if we now try to do this with the eBooks reference to the same array…

eBooks[0].Download();

… it won’t work - the Download method is not defined on the parent type. So, the answer must be “no”!

Well - turns out the right answer is actually “yes”: the code will compile.

The reason for that is that C# (and also Java) supports covariant array conversions. It basically means that if B is a subtype of A, an array of B will also be treated as a subtype of A and array insertions are checked at runtime. So, while the example above will compile, the assignment to books[0] will throw an ArrayTypeMismatchException.

Things get more complicated with generic containers such as Lists (covariant/contravariant type parameters in C#, and the notorious wildcard types in Java…), but that’s kinda expected.

For more, I recommend the Wikipedia article on Covariance and contravariance. It’s an interesting topic which tends to fry even the brains of experienced programmers.

Written on March 22, 2016. Please subscribe to my blog.