C# 面试题 目录

C# 中协变 (covariance) 和逆变 (contravariance) 的概念

推荐答案

在C#中,协变(covariance)和逆变(contravariance)是用于描述类型参数在继承关系中的行为的概念。它们主要用于泛型类型和委托类型中。

协变 (Covariance)

协变允许使用比原始指定的类型更派生的类型。在C#中,协变主要用于泛型接口和委托的返回类型。协变通过out关键字来标记类型参数。

例如:

在这个例子中,List<Dog>可以被赋值给IEnumerable<Animal>,因为DogAnimal的子类,而IEnumerable<T>接口的T是协变的。

逆变 (Contravariance)

逆变允许使用比原始指定的类型更通用的类型。在C#中,逆变主要用于泛型接口和委托的参数类型。逆变通过in关键字来标记类型参数。

例如:

在这个例子中,Action<Animal>可以被赋值给Action<Dog>,因为AnimalDog的父类,而Action<T>委托的T是逆变的。

本题详细解读

协变 (Covariance)

协变是指类型参数可以从更具体的类型转换为更通用的类型。在C#中,协变通常用于返回类型,因为它允许方法返回一个比声明的返回类型更具体的类型。

例如,假设有一个基类Animal和一个派生类Dog

我们可以定义一个协变的泛型接口:

然后我们可以这样使用:

这里,MyClass<Dog>实现了IMyInterface<Dog>,但由于T是协变的,所以可以将IMyInterface<Dog>赋值给IMyInterface<Animal>

逆变 (Contravariance)

逆变是指类型参数可以从更通用的类型转换为更具体的类型。在C#中,逆变通常用于参数类型,因为它允许方法接受比声明的参数类型更通用的类型。

例如,继续使用AnimalDog类,我们可以定义一个逆变的泛型接口:

然后我们可以这样使用:

这里,MyClass<Animal>实现了IMyInterface<Animal>,但由于T是逆变的,所以可以将IMyInterface<Animal>赋值给IMyInterface<Dog>

总结

  • 协变:允许将派生程度更大的类型赋值给派生程度更小的类型(out关键字)。
  • 逆变:允许将派生程度更小的类型赋值给派生程度更大的类型(in关键字)。

这些概念在C#中主要用于泛型接口和委托,使得类型转换更加灵活和安全。

纠错
反馈