博客
关于我
协变和逆变(转载)
阅读量:398 次
发布时间:2019-03-05

本文共 1463 字,大约阅读时间需要 4 分钟。

C# 4.0 中协变与逆变深入解析

前言

协变(Covariance)与逆变(Contravariance)是C# 4.0中最具挑战性的概念之一。虽然C#使用直观的inout关键字,使得在大多数情况下看似简单,但实际上其行为并非直观。在了解了这些概念后,我希望分享自己的理解,以助于其他开发者更好地掌握这一特性。

协变与逆变

首先,我们需要明确协变与逆变的定义。假设有两个类型TU,它们之间可能存在以下关系:

  • T < U:表示TU的子类型,即T表示的范围比U更窄。

根据上述定义,我们可以引入协变和逆变的概念:

  • 协变:如果T < U,且应用某操作f后,f(T) < f(U),则称f是协变的。
  • 逆变:如果T < U,且应用某操作f后,f(T) > f(U),则称f是逆变的。

以下是一个C#数组的典型协变示例。假设CatAnimal的子类,即Cat < Animal。应用数组化操作f后,Cat[]Animal[]的协变性如下:

  • Cat < Animal,因此Cat[] < Animal[]

这意味着我们可以将Cat[]赋值给Animal[],如下所示:

Cat[] cats = new[] { new Cat { Name = "Kitty" } };Animal[] animals = cats;

类型安全

C#是一个类型安全的语言,例如:

Animal animal = new Person(); // 错误,`Person`与`Animal`不兼容

然而,数组上的协变并不总是类型安全。例如:

Cat[] cats = new[] { new Cat { Name = "Kitty" } };Animal[] animals = cats;animals[0] = new Tiger { Name = "Tiger Lei" };

上述代码在运行时会抛出ArrayTypeMismatchException,因为Cat[]不能赋值给Animal[]。这表明C#对数组协变的支持并不总是类型安全,尽管在C# 1.0中首次引入了对数组协变的支持。

协变与逆变与泛型参数位置

泛型参数的位置影响其协变性和逆变性:

  • 输出位置(out参数):支持类型安全的协变。
  • 输入位置(in参数):支持类型安全的逆变。
  • 例如:

    • 对于IEnumerator<T>T是输出位置,支持协变。
    • 对于IComparer<T>T是输入位置,支持逆变。

    抓狂时刻

    在某些情况下,协变与逆变的应用可能会让人困惑。例如:

    public interface IFoo
    {}public interface IBar
    { void Method(IFoo
    foo);}

    如果T是逆变参数(in T),则IBar<T>中的T支持逆变。但若将T作为输入参数,编译器仍会报错。这表明在某些情况下,逆变的应用需要特别注意。

    不可变(Invariance)

    某些类型的泛型参数既不能支持协变,也不能支持逆变,称为不可变。例如,IList<T>中的T无法同时支持协变和逆变,因为这会导致类型安全问题。

    结论

    协变与逆变是C# 4.0中的核心特性,它们的理解对编写和使用泛型代码至关重要。通过合理地使用inout关键字,可以在类型安全的前提下充分利用这些特性,提升代码的灵活性和可读性。然而,在实际开发中,需要特别注意其局限性,避免因误用导致类型安全问题。

    转载地址:http://zolzz.baihongyu.com/

    你可能感兴趣的文章
    OpenCV与AI深度学习 | 实战|OpenCV实时弯道检测(详细步骤+源码)
    查看>>
    OpenCV与AI深度学习 | 实用技巧 | 使用OpenCV进行模糊检测
    查看>>
    OpenCV与AI深度学习 | 实践教程|旋转目标检测模型-TensorRT 部署(C++)
    查看>>
    OpenCV与AI深度学习 | 工业缺陷检测中数据标注需要注意的几个事项
    查看>>
    OpenCV与AI深度学习 | 干货 | 深度学习模型训练和部署的基本步骤
    查看>>
    OpenCV与AI深度学习 | 手把手教你用Python和OpenCV搭建一个半自动标注工具(详细步骤 + 源码)
    查看>>
    OpenCV与AI深度学习 | 水下检测+扩散模型:或成明年CVPR最大惊喜!
    查看>>
    OpenCV与AI深度学习 | 深入浅出了解OCR识别票据原理
    查看>>
    OpenCV与AI深度学习 | 深度学习检测小目标常用方法
    查看>>
    OpenCV与AI深度学习 | 超越YOLOv10/11、RT-DETRv2/3!中科大D-FINE重新定义边界框回归任务
    查看>>
    OpenCV与AI深度学习 | 高效开源的OCR工具:Surya-OCR介绍与使用
    查看>>
    OpenCV与AI深度学习|16个含源码和数据集的计算机视觉实战项目(建议收藏!)
    查看>>
    Opencv中KNN背景分割器
    查看>>
    OpenCV中基于已知相机方向的透视变形
    查看>>
    OpenCV中的监督学习
    查看>>
    opencv中读写视频
    查看>>
    OpenCV中遇到Microsoft C++ 异常 cv::Exception
    查看>>
    opencv之cv2.findContours和drawContours(python)
    查看>>
    opencv之namedWindow,imshow出现两个窗口
    查看>>
    opencv之模糊处理
    查看>>