为什么泛型不支持协变性?

假设

class S { }
class A : S { }
class B : S { }

下面的代码是可以编译通过的

S[] array = new A[5];
array[0] = new B();
List<S> list = new List<A>();

运行结果:

第一行代码是可以编译通过的

第二行代码运行时报错

第三行代码编译不通过。

问题1:为什么数组支持协变性?

因为Java有协变数组,所以.net的设计者的第一个版本时,也采取同样的策略。虽然这个功能在Java中是一个公认的“瑕疵”

问题2:为什么泛型不支持协变性?

泛型设计者认为与其在运行失败,不如在编译时就失败——静态类型语言的全部意义在于代码运行前找出错误。

为什么泛型不支持协变性?,布布扣,bubuko.com

时间: 2024-10-28 19:48:45

为什么泛型不支持协变性?的相关文章

编写高质量代码改善C#程序的157个建议——建议43:让接口中的泛型参数支持协变

建议43:让接口中的泛型参数支持协变 除了上一建议中提到的使用泛型参数兼容接口不可变性外,还有一种办法是为接口中的泛型声明加上out关键字来支持协变,如下所示: interface ISalary<out T> //使用out关键字 { void Pay(); } static void Main(string[] args) { ISalary<Programmer> s = new BaseSalaryCounter<Programmer>(); ISalary&l

11.C语言泛型的支持

1.C语言泛型实现 在前面我所编写的JWArray和JWList都是只能写定一种类型,那么为了在实际中使用方便,很自然想到类似C++中的泛型支持功能,C++中使用模板技术来实现泛型,但是在C中是不支持模板技术的,怎么来实现泛型呢? 如果你了解一点C++的模板技术的话,就知道其实这里的C++模板技术最简单的实现就是编译器对每一种类型都实现一次,然后调用的时候链接到不同类型的实现.那么既然这里C语言编译器本身不支持模板技术,那么我们就用手工来实现每一种类型的函数,然后在实际调用的时候直接链接到对应类

07.C#泛型的限制和可空类型的简单说明(三章3.5-四章4.1)

自己在写文章的同时,也是在学习,对于书中的语句很多其实没有太好的理解,读一本书,要消化!!!三章都是讲泛型的,最后写一下泛型的限制,对于本章学习的完结,one end,one begin. 看下面的代码 1 public class Teacher 2 { 3 public enum Flag { Chinese, English }; 4 public string Name { get; set; } 5 } 6 7 public class ChineseTeacher : Teacher

协变、逆变与不变:数组、泛型、与返回类型

转自:http://blog.csdn.net/yi_Afly/article/details/52071260 1. 前言 之前几篇博文,有些地方涉及到了协变性.逆变性与不变性在Java中的表现,所以这篇博文将重点记录这方面的内容,并辅以JDK源码中的一些实例,加以说明. 2. 定义 这里讨论的协变.逆变与不变都是编程语言中的概念.下面介绍定义: 若类A是类B的子类,则记作A ≦ B.设有变换f(),若: 当A ≦ B时,有f(A)≦ f(B),则称变换f()具有协变性. 当A ≦ B时,有f

细说泛型

C#2的头号亮点 : 泛型 在C#1中,Arraylist总是会给人带来困扰,因为它的参数类型是Object,这就让开发者无法把握集合中都有哪些类型的数据.如果对string类型的数据进行算术操作那自然会报错,但是遺憾的是在編譯期不会给你任何的提示 C#2中引入的泛型极其耀眼,甚至有些人会因为泛型而忽略C#2中其它新加入的特性 回到上面的问题,ArrayList带来的不仅仅是上面那些困扰,Object是所有类型的基类,但是我们在开发中它幾乎不会有它的身影,因为它包容一切,但是我们需要使用int做

.NET面试题系列[8] - 泛型

泛型 泛型相比反射,委托等较为抽象的概念要更接地气得多,而且在平常工作时,我们几乎时刻都和泛型有接触.大部分人对泛型都是比较熟悉的. 泛型集合是类型安全的集合.相对于泛型System.Collections.Generic,我们有类型不安全的集合System.Collections,其中的成员均为Object类型.一个经典的例子是ArrayList. 在使用ArrayList时,我们可以插入任意类型的数据,如果插入值类型的数据,其都会装箱为Object类型.这造成类型不安全,我们不知道取出的数据

C#规范整理&#183;泛型委托事件

基于泛型,我们得以将类型参数化,以便更大范围地进行代码复用.同时,它减少了泛型类及泛型方法中的转型,确保了类型安全.委托本身是一种引用类型,它保存的也是托管堆中对象的引用,只不过这个引用比较特殊,它是对方法的引用.事件本身也是委托,它是委托组,C#中提供了关键字event来对事件进行特别区分.   一旦我们开始编写稍微复杂的C#代码,就肯定离不开泛型.委托和事件. 1.总是优先考虑泛型 泛型的优点是多方面的,无论是泛型类还是泛型方法都同时具备可重用性.类型安全和高效率等特性,这都是非泛型类和非泛

泛型及java中的泛型

当作笔记整理的~~~ 首先,引出堆对象这个概念. 什么是堆对象,就是程序在运行过程中可以随时建立或者删除的对象,可以用new运算符(或malloc函数)或者delete运算符(或free函数).泛型可以看作是一类堆对象. 泛型是程序设计语言的一种特性.允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明. 各种程序设计语言和其编译器.运行环境对泛型的支持均不一样.将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型. 泛型的定义主要有两种:1.在程序编

Java中泛型的协变

在工作中遇到一个问题,用代码描述如下: package test; import java.util.LinkedList; import java.util.List; public class ListTest {     public void func(List<Base> list) {     }     public static void main(String args[]) {         ListTest lt = new ListTest();         Li