I generally understand interfaces, inheritance and polymorphism, but one thing has me puzzled.
In this example, Cat implements IAnimal
IList is not a covariant interface (or it would be IList). This is because IList both takes type T as a parameter and returns it as a return value from methods, which makes covariance problematic.
For example, if in your example:
IList
You wanted to add a new cat, from cats, it would allow:
cats.Add(new Dog());
assuming Dog also implemented IAnimal, this is obviously incorrect and wouldn't work. Which is why IList is not a covariant or contravariant interface.