The short answer is because a function Foo can be implemented like this:
void Foo(IList<IShape> c)
{
c.Add(new Square());
}
If you passed a List<Circle> to Foo, the provided type would not be capable of storing the Square, even though the type signatures claim it is okay. IList<T> is not covariant: the general IList<Circle> cannot be an IList<IShape> because it cannot support the addition of arbitrary shapes.
The fix is to use IEnumerable<IShape> to accept arguments in Foo, but that won't work in all cases. IEnumerable<T> is covariant: the specialized IEnumerable<Circle> fits the contract of the general IEnumerable<IShape>.
This behavior is also a Good Thing. The classic example of something that is covariant when it should not be is an array. The following code will compile, but will fail at runtime:
void Bar()
{
// legal in C#:
object[] o = new string[10];
// fails with ArrayTypeMismatchException: can't store Int in a String[]
o[0] = 10;
}