在C#编程中,泛型(Generics)为我们提供了类型安全和代码复用的强大能力。而C#协变(Covariance)与C#逆变(Contravariance)则是泛型高级特性中的重要概念,它们让泛型接口和委托在类型转换时更加灵活。本文将用通俗易懂的方式,带你从零开始掌握这两个概念,并通过实际代码示例加深理解。
简单来说:
IEnumerable<Cat> 赋值给 IEnumerable<Animal>,前提是 Cat 继承自 Animal。Action<Animal> 赋值给 Action<Cat>。
协变使用 out 关键字声明,表示该泛型参数只能作为输出(返回值),不能作为输入参数。
来看一个例子:
// 定义基类和派生类class Animal { }class Cat : Animal { }class Program{ static void Main() { // 创建一个 Cat 的列表 var cats = new List<Cat> { new Cat(), new Cat() }; // 协变:IEnumerable<T> 是协变的(定义为 IEnumerable<out T>) IEnumerable<Animal> animals = cats; // ✅ 合法! foreach (var animal in animals) { Console.WriteLine(animal.GetType().Name); } }} 这里之所以能成功,是因为 IEnumerable<T> 接口被定义为:
public interface IEnumerable<out T> 注意 out 关键字,它告诉编译器:这个泛型参数 T 只用于返回值,不会被修改,因此可以安全地进行“向上转型”。
逆变使用 in 关键字声明,表示该泛型参数只能作为输入(方法参数),不能作为返回值。
看下面的例子:
class Animal { }class Cat : Animal { }class Program{ static void Feed(Animal animal) { Console.WriteLine("喂动物!"); } static void Main() { // Action<T> 是逆变的(定义为 Action<in T>) Action<Cat> feedCat = Feed; // ✅ 合法! feedCat(new Cat()); // 调用时传入 Cat,但 Feed 方法接收 Animal }} 这是因为 Action<T> 委托被定义为:
public delegate void Action<in T>(T obj); 由于 T 只作为输入参数,传入一个 Cat 给接受 Animal 的方法是安全的(因为 Cat 是 Animal 的子类)。
你也可以自己定义支持协变或逆变的泛型接口:
// 协变接口:只能返回 Tinterface IProducer<out T>{ T Get();}// 逆变接口:只能接收 Tinterface IConsumer<in T>{ void Consume(T item);}// 实现class AnimalProducer : IProducer<Animal>{ public Animal Get() => new Animal();}class CatConsumer : IConsumer<Cat>{ public void Consume(Cat cat) => Console.WriteLine("吃猫粮");}// 使用IProducer<Animal> producer = new AnimalProducer();IProducer<Cat> catProducer = null; // ❌ 不能反过来!协变只支持“向上”IConsumer<Cat> consumer = new CatConsumer();IConsumer<Animal> animalConsumer = consumer; // ✅ 逆变:Animal 更通用,可赋值给 Cat 消费者 out)和逆变(in)**仅适用于接口和委托**,不适用于类。out 的泛型参数不能出现在方法参数中(只能作为返回值)。in 的泛型参数不能作为返回值(只能作为参数)。int、struct)不支持。通过本文,你应该已经掌握了 C#协变 与 C#逆变 的基本原理和使用场景。它们是 C#泛型教程 中不可或缺的高级特性,能让你写出更灵活、更安全的代码。记住:
out → 协变 → 只出不进 → 用于返回值in → 逆变 → 只进不出 → 用于参数掌握这些知识后,你在阅读 .NET 框架源码或设计自己的泛型 API 时,将更加得心应手!
希望这篇关于 泛型协变逆变 的教程对你有帮助!
本文由主机测评网于2025-12-28发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20251213515.html