В каких случаях использовать Ковариантность и Контрвариантность?
Возвращать из метода наиболее конкретный тип, а в аргументах принимать наиболее общий.
https://en.wikipedia.org/wiki/Covariance_and_contr...
For example, in C#, if Cat is a subtype of Animal, then:

 IEnumerable<Cat> is a subtype of IEnumerable<Animal>. The subtyping is preserved because IEnumerable<T> is covariant on T.
 Action<Animal> is a subtype of Action<Cat>. The subtyping is reversed because Action<T> is contravariant on T.

Даже не знаю, что добавить.