C# 中的协变和逆变

2025年4月25日 | 阅读 4 分钟

协变(Covariance)逆变(Contravariance)主要与 C# 中的泛型类型相关。特别是在处理继承和泛型集合时,这些概念可以实现类型之间更灵活、更自然的关联。

C# 中的协变是什么?

协变允许将更派生的类型隐式转换为较少派生的类型。换句话说,它允许我们在需要基类型的情况下使用派生类型。将更专业的类型始终视为其基类型是有意义的。C# 支持返回类型场景中的协变。C#。换句话说,如果方法返回泛型类型,我们可以使用派生类型代替最初定义的类型。由于协变,如果派生类继承自基类并且方法 GetItem 返回基类,我们可以将结果赋值给派生类型的变量。

C#中的实现

C# 中的逆变是什么?

协变与逆变是相反的关系。它允许将较少派生的类型隐式转换为更派生的类型。换句话说,它允许在期望派生类型的情况下使用基类型。

逆变主要适用于涉及方法参数的场景。因此,如果方法参数接受泛型类型,我们可以使用基类型代替最初定义的类型。

因为 Derived 比 Base 更专业化,所以逆变允许我们向接受 Base 作为参数的方法传递 Derived 类型的参数。

C#中的实现

协变和逆变在 C# 中主要用于泛型接口和委托。特别是在涉及继承集合的场景中,它们确保类型安全并允许更具创造性地使用泛型类型。

在 C# 中,可以使用 out 和 in 关键字在泛型类型参数声明中实现协变和逆变。in 关键字启用逆变,out 关键字启用协变。

示例

让我们举一个例子来说明 C# 中的协变和逆变。

输出

Returning Derived
Derived
Printing Base
Derived

说明

  • 协变: 我们命名的 returnDerived 委托是一个 Func。此委托表示的方法接受一个 Derived 对象作为输入并输出一个 Base 对象。我们将 GetDerived 方法分配给此委托,该方法返回一个 Derived 对象。作为协变的一个示例,即使委托被定义为返回 Base,它也允许返回更派生的类型 (Derived)。
  • 逆变: 我们有一个名为 acceptBase 的 Action 委托。此委托表示的方法接受一个 Base 对象作为输入。此委托被赋予一个名为 Print 的方法,该方法接受一个 Base 参数作为输入,但返回一个 Derived 参数。由于逆变,我们可以将接受较少派生类型 (Base) 的委托分配给期望更多派生类型 (Derived) 的委托。