In his book C# in Depth, Jon Skeet tries to answer the following question:
Why can't I convert
List<string>
toList<object>
?
To explain it, he started with a code-snippet, which includes these two lines:
Animal[] animals = new Cat[5]; //Ok. Compiles fine!
List<Animal> animals = new List<Cat>(); //Compilation error!
As the comments read, the first one compiles fine, but the second one gives compilation error. I didn't really understand the reason. Jon Skeet explained this with saying only that first one compiles because in .NET, arrays are covariant, and second one doesn't compile because generics are not covariant (they're invariant, instead). And furthermore, arrays are covariant in .NET, because arrays are covariant in Java and .NET made it similar to Java.
I'm not completely statisfied with this short-answer. I want to know it in a more detail, with some insight into how compiler handles the difference, and how it generates IL and all.
Also, if I write (taken from the book itself):
Animal[] animals = new Cat[5]; //Ok. Compiles fine!
animals.Add(new Turtle()); //this too compiles fine!
It compiles fine, but fails at runtime. If it has to fail at runtime(which means what I write shouldn't make sense), then why does it compile in the first place? Can I use the instance animals
in my code, and which also runs with no runtime error?