Created
June 28, 2013 16:18
-
-
Save n3dst4/5885949 to your computer and use it in GitHub Desktop.
A walkthough of why .net people care about variance in generic type parameters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// generic type: | |
public class Bag<T> {} | |
// simple usage: | |
Bag<Fruit> myBag; | |
myBag = new Bag<Fruit>(); | |
// so far so good | |
// surely if we can do | |
Fruit f = new Apple(); | |
// then we should be able to do: | |
Bag<Fruit> fruitBag = new Bag<Apple>(); | |
// right? no, because now we have something which is ostensibly a Bag<Fruit>, | |
// but if you try to do: | |
fruitBag.Add(new Banana()); | |
// you're trying to add a Banana to something which is actually a Bag<Apple>. | |
// so okay, let's go the other way. can we do: | |
Bag<Fruit> fruitBag = new Bag<Food>(); | |
// that would solve the first problem, because now we can do this line: | |
fruitBag.Add(new Banana()); | |
// which is just adding a Banana to a Bag<Food> so that's okay. The problem is | |
// that Bag<Food> may contain other things: | |
Bag<Food> foodBag = new Bag<Food>(); | |
Bag<Fruit> fruitBag = foodBag; | |
foodBag.Add(new Sausage()); | |
Fruit myFruit = fruitBag.Get(); | |
// yuck. we just pulled a sausage out of a bag of fruit. that can't be | |
// right. | |
// | |
// so, that's why, everything else being equal, you can't use polymorphism with | |
// generic types. | |
// | |
// note that you *can* absolutely use normal polymorphism with the objects that | |
// pass as arguments, i.e. you can always do: | |
Bag<Fruit> fruitBag = new Bag<Fruit>(); | |
fruitBag.Add(new Banana()); | |
// The restriction applies to the types of the conscrete Bag instance and the | |
// Bag variable it's assigned to. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment