逆变
IComparer<T>
何时是不同的 IComparer<T1>
的子类型?当 T1
是 T
的子类型时。IComparer
在 T
参数中是逆变的,这意味着 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
消耗了 T
s 但不生产它们。可以比较任何两个 Animal
s 的对象可用于比较两个 Dog
s。
使用 in
关键字声明 Contravariant 类型参数,因为该参数必须仅用作输入。
interface IComparer<in T> { /* ... */ }
声明为逆变的类型参数可能不会显示为输出。
interface Bad<in T>
{
T GetT(); // type error
}