I was reading up on covariance and contravariance today and I came across a post on stack exchange where Jon Skeet was explaining invariance at the class level. He used an example of fruit and why allowing covariance at that level would be a bad thing:
//Bad
List<Banana> bunchOfBananas = new List<Banana>();
// This would be valid if List<T> were covariant in T
List<Fruit> fruitBowl = bunchOfBananas;
fruitBowl.Add(new Apple());
Banana banana = bunchOfBananas[0];
So, how does this account for having a list of Fruit that you would add instances of class that inherit from Fruit? For example:
//Good
List<Fruit> fruitBowl = new List<Fruit>();
fruitBowl.Add(new Apple());
fruitBowl.Add(new Banana());
I've done this in the past and it always behaves as expected. Why doesn't the CLR look at the type of fruitBowl? Is it because you are setting the value of your fruitBowl to a list of Bananas first which is covariant to a list of Fruit and then trying to add an Apple to a collection whose type is really List<Banana>
?
Thanks to Matt below. It helps to remember that you're dealing with reference types. Downvote this forever.