Can someone explain why this operation is invalid?

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.

Answers


I think what you are missing is that when you do in your first example:

List<Fruit> fruitBowl = bunchOfBananas;

You are not making a copy of bunchOfBananas into a List<Fruit>. Instead, you are creating a reference to a bunch of bananas, and that reference could be used to add any kind of fruit.

Thus when you do:

fruitBowl.Add(new Apple());

you would not be adding an apple to a list of fruit; you'd be adding an apple to the List<Banana> bunchOfBananas, which is clearly A Bad Thing.


Need Your Help

Unable to deserialize CSLA request in soap message sent by WCF (C#)

wcf deserialization csla

I am learning WCF so my apologies if my terminology is off here and there.

Missing crt0.o file with cross-i386 gcc

c gcc cross-compiling crt newlib

I can't find out why crt0.o or crt1.o are not provided for i386 targets by newlib as it is the case for powerpc, arm, etc. targets.