Skip to content

Instantly share code, notes, and snippets.

@n3dst4
Created June 28, 2013 16:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n3dst4/5885949 to your computer and use it in GitHub Desktop.
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
// 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