在C#编程中,泛型委托是提升代码复用性和灵活性的重要工具。而协变(covariance)和逆变(contravariance)则是泛型委托中常被初学者忽略但极其强大的特性。本文将用通俗易懂的方式,带你从零开始掌握C#泛型委托的协变与逆变应用。
简单来说:
Animal 的方法可以赋值给返回 Dog 的委托(前提是 Dog 继承自 Animal)。Animal 参数的方法可以赋值给接受 Dog 参数的委托。C# 提供了两个内置泛型委托:Func<TResult> 和 Action<T>。它们分别用于有返回值和无返回值的方法。
其中:
Func<out TResult> 支持协变(注意 out 关键字)Action<in T> 支持逆变(注意 in 关键字)假设我们有以下类结构:
public class Animal{ public virtual string Speak() => "...";}public class Dog : Animal{ public override string Speak() => "汪汪!";}public class Cat : Animal{ public override string Speak() => "喵喵!";} 现在我们定义一个返回 Animal 的方法,并将其赋值给 Func<Dog> 委托:
// 返回 Animal 的方法static Animal GetAnimal() => new Dog();// 协变:Func<Animal> 可以赋值给 Func<Dog>Func<Dog> getDog = GetAnimal; // ✅ 合法!因为 Dog 是 Animal 的子类Dog myDog = getDog();Console.WriteLine(myDog.Speak()); // 输出:汪汪! 这就是协变的力量——它让泛型委托更加灵活。
再来看逆变。我们定义一个接受 Animal 参数的方法:
// 接受 Animal 参数的方法static void FeedAnimal(Animal animal){ Console.WriteLine($"喂 {animal.GetType().Name} 吃饭!");}// 逆变:Action<Animal> 可以赋值给 Action<Dog>Action<Dog> feedDog = FeedAnimal; // ✅ 合法!因为 Dog 是 Animal 的子类feedDog(new Dog()); // 输出:喂 Dog 吃饭! 这里,虽然 FeedAnimal 接受的是 Animal,但我们却能把它当作 Action<Dog> 使用。这就是逆变——参数类型可以“向上兼容”。
协变和逆变让 C# 泛型委托更符合“里氏替换原则”(Liskov Substitution Principle),即子类对象可以替换父类对象而不破坏程序逻辑。通过 out 和 in 关键字,C# 在编译期就保证了类型安全,同时提升了代码的通用性。
- C#泛型委托如 Func 和 Action 内置支持协变与逆变。
- 协变(out)用于返回值,允许“更具体的类型”。
- 逆变(in)用于参数,允许“更通用的类型”。
- 正确使用这些特性,可以写出更灵活、更安全的 C# 代码。
无论你是刚接触 C#委托教程 的新手,还是想深入理解 委托covariance contravariance 的开发者,掌握协变与逆变都将极大提升你的编程能力。希望这篇关于 C#泛型委托 的文章对你有所帮助!
本文由主机测评网于2025-12-24发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/20251212247.html