推荐答案
在C#中,协变(covariance)和逆变(contravariance)是用于描述类型参数在继承关系中的行为的概念。它们主要用于泛型类型和委托类型中。
协变 (Covariance)
协变允许使用比原始指定的类型更派生的类型。在C#中,协变主要用于泛型接口和委托的返回类型。协变通过out
关键字来标记类型参数。
例如:
IEnumerable<Animal> animals = new List<Dog>();
在这个例子中,List<Dog>
可以被赋值给IEnumerable<Animal>
,因为Dog
是Animal
的子类,而IEnumerable<T>
接口的T
是协变的。
逆变 (Contravariance)
逆变允许使用比原始指定的类型更通用的类型。在C#中,逆变主要用于泛型接口和委托的参数类型。逆变通过in
关键字来标记类型参数。
例如:
Action<Animal> animalAction = (Animal a) => Console.WriteLine(a.Name); Action<Dog> dogAction = animalAction;
在这个例子中,Action<Animal>
可以被赋值给Action<Dog>
,因为Animal
是Dog
的父类,而Action<T>
委托的T
是逆变的。
本题详细解读
协变 (Covariance)
协变是指类型参数可以从更具体的类型转换为更通用的类型。在C#中,协变通常用于返回类型,因为它允许方法返回一个比声明的返回类型更具体的类型。
例如,假设有一个基类Animal
和一个派生类Dog
:
public class Animal { } public class Dog : Animal { }
我们可以定义一个协变的泛型接口:
public interface IMyInterface<out T> { T GetItem(); }
然后我们可以这样使用:
IMyInterface<Animal> animalInterface = new MyClass<Dog>();
这里,MyClass<Dog>
实现了IMyInterface<Dog>
,但由于T
是协变的,所以可以将IMyInterface<Dog>
赋值给IMyInterface<Animal>
。
逆变 (Contravariance)
逆变是指类型参数可以从更通用的类型转换为更具体的类型。在C#中,逆变通常用于参数类型,因为它允许方法接受比声明的参数类型更通用的类型。
例如,继续使用Animal
和Dog
类,我们可以定义一个逆变的泛型接口:
public interface IMyInterface<in T> { void SetItem(T item); }
然后我们可以这样使用:
IMyInterface<Dog> dogInterface = new MyClass<Animal>();
这里,MyClass<Animal>
实现了IMyInterface<Animal>
,但由于T
是逆变的,所以可以将IMyInterface<Animal>
赋值给IMyInterface<Dog>
。
总结
- 协变:允许将派生程度更大的类型赋值给派生程度更小的类型(
out
关键字)。 - 逆变:允许将派生程度更小的类型赋值给派生程度更大的类型(
in
关键字)。
这些概念在C#中主要用于泛型接口和委托,使得类型转换更加灵活和安全。