逆变

IComparer<T> 何时是不同的 IComparer<T1> 的子类型?当 T1T 的子类型时。IComparerT 参数中是逆变的,这意味着 IComparer 的子类型关系与 T方向相反

class Animal { /* ... */ }
class Dog : Animal { /* ... */ }

IComparer<Animal> animalComparer = /* ... */;
IComparer<Dog> dogComparer = animalComparer;  // IComparer<Animal> is a subtype of IComparer<Dog>
// animalComparer = dogComparer;  // Compilation error - IComparer<Dog> is not a subtype of IComparer<Animal>

具有给定类型参数的逆变泛型类型的实例可隐式地转换为具有更多派生类型参数的相同泛型类型。

这种关系成立,因为 IComparer 消耗了 Ts 但不生产它们。可以比较任何两个 Animals 的对象可用于比较两个 Dogs。

使用 in 关键字声明 Contravariant 类型参数,因为该参数必须仅用作输入

interface IComparer<in T> { /* ... */ }

声明为逆变的类型参数可能不会显示为输出。

interface Bad<in T>
{
    T GetT();  // type error
}