<out T>
表示T
是协变的。
可以将一系列长颈鹿视为一系列动物似乎是合理的。接口的“协变”意味着“如果存在从 to 的隐式引用转换,那么也存在从Giraffe
to的隐式引用转换。构造类型的可转换性与类型参数的可转换性“在同一方向上变化”。Animal
I<Giraffe>
I<Animal>
例子:
// Valid! // Invalid!
// Every giraffe is an animal // Not every animal is a giraffe
IEnumerable<Giraffe> giraffes = ...; IEnumerable<Animal> animals = ...;
IEnumerable<Animal> animals = giraffe; IEnumerable<Giraffe> giraffes = animals;
Animal animal = animals.First(); Giraffe giraffe = giraffes.First();
<in T>
表示T
是逆变的。
可以比较两只动物的代码也可以比较两只长颈鹿,这似乎是合理的。界面的“逆变”与方向相反的协方差相同。这意味着“如果存在从 to 的隐式引用转换,那么也存在从Giraffe
to的隐式引用转换。构造类型的可转换性“以相反的方向变化”作为类型参数的可转换性。Animal
I<Animal>
I<Giraffe>
例子:
// Valid! // Invalid!
// Animal comparer can compare // Giraffe comparer cannot compare
// giraffes // arbitrary animals
IComparer<Animal> animalC = ...; IComparer<Giraffe> giraffeC = ...;
IComparer<Giraffe> giraffeC = animalC; IComparer<Animal> animalC = giraffeC;
int result = giraffeC.Compare(x, y); int result = animalC.Compare(x, y);
看: