Imagine what would happen if you could do such a thing. You could write code like the following:
IList<Child> children = new List<Child>();
IList<Parent> parents = children;
parents.Add(new Parent());
Note that parents
is still a reference to the same object as children
, however we have managed to add an object that is not an instance of Child
to a IList<Child>
!
As another answer has mentioned, this is all to do with the issue of covariance (closely related to an area of mathematics known as Category Theory - interesting if you get a chance to look at it).
Essentially, if we write T-> S
, for two types where S
is polymorphic to T
, say Parent -> Child
, then a generic is covariant if it preserves this relationship. For example IEnumerable
is a covariant because IEnumerable<Object> -> IEnumerable<String>
. The compiler knows this, as you can cast an IEnumerable<String>
to an IEnumerable<Object>
.