1 of 2

This is mostly a rewording of this excellent blog by Eric Lippert:

C# sub types have always been assignment compatible with their base types e.g. given that Teacher is derived from Person Person p = new Teacher(); is valid i.e. there is a relation isAssignable(x,y) which is true IFF x= y is allowed.

before C# 4 generic collections of sub types were not assignment compatible with generic collections of base types (i.e. List<Teacher> does not derive from List<Person> so you could not assign List<Teacher> to a List<Person>) i.e. isAssignable(List<x>,List<y>) was always false regardless of the value of isAssignable(x,y)

C# 4 adds variance for generic types, this allows a generic type to be *variant over a projection from T -> A<T>. which means that for covariant parameters, relations which hold for T,U hold for A<T>,A<U>, and for contra-variant the relation is reversed. i.e. for the relationship isAssignable(x,y) a types that are covariant over the projection like List<>s has the same relations as their generic parameters so isAssignable(x,y) == isAssignable(List<x>,List<y>)