http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx

C# implements variance in two ways. Today, the broken way.

Ever since C# 1.0, arrays where the element type is a reference type are covariant. This is perfectly legal:

Animal[] animals = new Giraffe[10];

Since Giraffe is smaller than Animal, and “make an array of” is a covariant operation on types, Giraffe[] is smaller thanAnimal[], so an instance fits into that variable.

Unfortunately, this particular kind of covariance is broken. It was added to the CLR because Java requires it and the CLR designers wanted to be able to support Java-like languages. We then up and added it to C# because it was in the CLR. This decision was quite controversial at the time and I am not very happy about it, but there’s nothing we can do about it now.

Why is this broken? Because it should always be legal to put a Turtle into an array of Animals. With array covariance in the language and runtime you cannot guarantee that an array of Animals can accept a Turtle because the backing store might actually be an array of Giraffes.

This means that we have turned a bug which could be caught by the compiler into one that can only be caught at runtime. This also means that every time you put an object into an array we have to do a run-time check to ensure that the type works out and throw an exception if it doesn’t. That’s potentially expensive if you’re putting a zillion of these things into the array.

Yuck.

Unfortunately, we’re stuck with this now. Giraffe[] is smaller than Animal[], and that’s just the way it goes.

I would like to take this opportunity to clarify some points brought up in comments to Part One.

First, by "subtype" and "supertype" I mean "is on the chain of base classes" for classes and "is on the tree of base interfaces" for interfaces. I do not mean the more general notion of "is substitutable for". And by “bigger than” and “smaller than” I explicitly do NOT mean “is a supertype of” and “is a subtype of”. It is the case that every subclass is smaller than its superclass, yes, but not vice versa. That is, it is not the case that every smaller type is a subtype of its larger type.Giraffe[] is smaller than both Animal[] and System.Array. Clearly Giraffe[] is a subtype of System.Array, but it isemphatically not a subtype of Animal[]. Therefore the “is smaller than” relationship I am defining is more general than the “is a kind of” relationship. I want to draw a distinction between assignment compatibility (smaller than) and inheritance (subtype of).

Next time we’ll discuss a kind of variance that we added to C# 2.0 which is not broken.

Covariance and Contravariance in C#, Part Two: Array Covariance的更多相关文章

  1. Covariance and Contravariance (C#)

    Covariance and Contravariance (C#) https://docs.microsoft.com/en-us/dotnet/articles/csharp/programmi ...

  2. Covariance and Contravariance in C#, Part One

    http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.a ...

  3. Co-variant array conversion from x to y may cause run-time exception

    http://stackoverflow.com/questions/8704332/co-variant-array-conversion-from-x-to-y-may-cause-run-tim ...

  4. 协变(covariance),逆变(contravariance)与不变(invariance)

    协变,逆变与不变 能在使用父类型的场景中改用子类型的被称为协变. 能在使用子类型的场景中改用父类型的被称为逆变. 不能做到以上两点的被称为不变. 以上的场景通常包括数组,继承和泛型. 协变逆变与泛型( ...

  5. Covarience And ContraVariance

    using System; using System.Collections.Generic; using System.IO; namespace CovarientAndContraVarient ...

  6. A geometric interpretation of the covariance matrix

    A geometric interpretation of the covariance matrix Contents [hide] 1 Introduction 2 Eigendecomposit ...

  7. C#(转自wiki)

    C#是微软推出的一种基于.NET框架的.面向对象的高级编程语言.C#的发音为"C sharp",模仿音乐上的音名"C♯"(C调升),是C语言的升级的意思.其正确 ...

  8. Nemerle Quick Guide

    This is a quick guide covering nearly all of Nemerle's features. It should be especially useful to a ...

  9. Scala入门指南与建议

    最近在学习使用Scala语言做项目,感觉这门语言实在是太优美了!作为一个本科数学.研究生机器学习专业的混合人才(哈哈),这门语言真的是满足了普通计算机编程(告诉计算机怎么做)和函数式编程(告诉计算机做 ...

随机推荐

  1. StrHelper

    public class StrHelper { private static string passWord; //加密字符串 /// <summary> /// 判断输入是否数字 // ...

  2. IO流01_File类

    [分类] Java的IO通过java.io包下的类和接口来支持. 1.按照流向: 输入流     输出流 2.按照操作数据的大小: 字节流( 8位字节 )     字符流( 16位字节 ) 3.按照角 ...

  3. 04_线程的创建和启动_使用Callable和Future的方式

    [简述] 从java5开始,java提供了Callable接口,这个接口可以是Runnable接口的增强版, Callable接口提供了一个call()方法作为线程执行体,call()方法比run() ...

  4. dorado抽取js

    dorado创建的视图文件如果有控件拥有事件的话,那么它是可以抽取js的, 右键视图->抽取JavaScript 然后就会出现一个同名的.js文件 (注意,所有的属性需要有id,因为js需要绑定 ...

  5. 把URL传递参数转变成自定义实体方法

    先定义下要获取的实体: public class InputClass { public long Id { get; set; } public int Status { get; set; } p ...

  6. android驱动程序之 - sensor

    上图是android系统架构图,从中可以得知,sensor必贯穿架构的各个层次.按照架构层次,下面从五个方面来分析sensor架构: 1. sensor架构之App层: 2. sensor架构之Fra ...

  7. linux RedHat6.4下nginx安装

    安装rpm 检测是否有已安装rpm包: rpm–qa | grep pcre rpm–qa | grep zlib rpm–qa | grep openssl 若没有则需安装(这些包可以在redhat ...

  8. VS2013中Django流水账笔记--配置环境

    一.开发环境 Win7 64位搭建开发环境.需要准备VS2013.Python34.PTVS2013. 1.http://pytools.codeplex.com/ 下载工具,下载之后进行安装即可,我 ...

  9. Yii表单模型使用及以数组形式提交表单数据

    按Yii文档里的描述,Yii在处理表单的一般过程是: 创建表单对应的模型类,设置字段验证规则 创建表单提交对应的action,处理提交的内容 在视图中创建表单form 在刚刚的一个小项目里,想使用aj ...

  10. 面向站长和网站管理员的Web缓存加速指南

    详细了解HTTP缓存控制及为什么要缓存. 英文版: http://www.mnot.net/cache_docs/ 中文版:http://www.chedong.com/tech/cache_docs ...