C#中的协变性与逆变性, Part Two: 数组协变性
来源:互联网 发布:sizeof 数组 编辑:程序博客网 时间:2024/05/19 04:56
C#用两种方式实现了可变性。今天,我们讲讲有缺陷的那种方法。
自从C# 1.0,存储引用类型元素的Array是可变的。所以下面的代码是合法的:
Animal[] animals = new Griaffe[10];
因为Giraffe要比Animal小,并且“生成某种类型的Array”是协变操作,Giraffe[]比Aniaml[]小,所以实例可以被赋予那个变量。
很不幸,在这种类型的可变性是有缺陷的。因为Java可以这么做,CLR的设计者想要支持像Java一样的语言,所以它被添加到CLR中。又因为它存在于CLR中,所以我们紧接着把它加到C#里面。这个决定在当时很有争议,我对此不满,但是我们也阻止不了。
为什么这是有缺陷的?因为把Turtle添加到Animals Arrarys应该总是合法的。但是因为数组的协变性和运行时的协变性,你不能保证一个Turtle可以被添加到Animals数据中,因为这个Animals数组的实例可能是Giraffes。(就像上面说的)
这意味着我们把一个本可以被编译器捕获的Bug变成了只能在运行时被捕获的Bug。这也意味着每次你向数组添加一个对象,我们必须执行一次运行时检查来保证类型匹配,或者在类型不匹配的时候抛出异常。如过你想数组中添加了很多这样的东西,那么代价是非常昂贵的。
不幸的是。。我们还要忍受这个。。(是的,我试了一下。。)
我想要借着这个机会阐述Part One中出现的一些观点。
首先,通过“子类”和“父类”,我想表达的意思是,“它们位于基类的继承链上”。我没有表达“可以替换的”这个概念。通过“大于”和“小于”,我特意不想表达“子类”和“基类”的意思。的确,子类是比父类都小,但小的类不一定是大的类的子类。Giraffe[]比Animal[]和System.Array都小,很明显Giraffe[]是System.Array的子类,但**不是**Animal[]的子类。因此,“更小”这种关系比“是一个”这种关系更宽泛。我想要区分一下赋值兼容性和继承。
下次我们将讨论C#2.0中可靠的可变性。
- C#中的协变性与逆变性, Part Two: 数组协变性
- C#中的协变性与逆变性
- c#中的协变性与逆变性,Part Three:方法组转换的可变性
- C#的协变性和逆变性
- C#4.0中的新功能:协变性和逆变性
- 浅谈C#4.0协变性与逆变性
- Java 协变性 逆变性
- 数组的协变性与范型的不可变性
- Java 协变性 逆变性 学习笔记
- java 协变性 逆变性 学习笔记
- java里的协变性与逆变性
- Java基本学习:数组--协变性
- C#4.0新特性(3):变性 Variance(逆变与协变)
- java 协变性和兼容性
- 深入理解泛型(二) 协变性和逆变性
- 并发与不可变性
- 并发与不可变性
- 以java为例理解协变性
- Python 处理微信网页版消息中的emoji表情在命令行中显示
- file类的常用方法
- Java 多线程7:ThreadLocal 类
- word2vector & paragraph2vector 技术分享
- JS类型检测(typeof和instanceof)
- C#中的协变性与逆变性, Part Two: 数组协变性
- 【校招笔试】通过考试(dp)
- 京东2017实习生招聘在线笔试编程题题解
- SQL回顾二
- P3369 【模板】普通平衡树(Treap/SBT)
- POJ 2576 Tug of War 二维费用背包
- FlyMCU烧写程序结束后不自动运行程序,需要手动复位后才可以运行的解决
- C#编写简单的数据库增删改查(二)
- C语言动态数组的创建