摘要 ● 协变和逆变的定义是什么?给我们带来了什么便利?如何应用? ● 对于可变的泛型接口,为什么要区分成协变的和逆变的两种?只要一种不是更方便吗? ● 为什么还有不可变的泛型接口,为什么有的泛型接口要故意声明成不可变的? ● 复合的可变泛型接口遵循哪些规则? ● 协变和逆变的数学定义是什么?如何利用数学模型解释C#4里的协变和逆变的规则? 前言 协变和逆变是c#4.0引入的新概念,主要是针对于泛型而言的.有了它们,我们可以更准确的定义泛型委托和接口. 首先举个栗子,比如IEnumerable<…
泛型接口和泛型委托中经常使用可变性 in  逆变,out  协变 从 list<string>转到list<object> 称为协变 (string 从object 派生,那么 string 转成object 是合理的,子类替换父类是合理的,) 从list<object> 转到 list<string> 称为逆变 (经object 转成string ,将父类转成子类,是不合理的,称为逆变) 1.逆变代码掩饰 static void Main(string[]…
逆变(Contravariance)/协变(Covariance) 1. 基本概念 官方: 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型.协变/逆变只支持委托.泛型接口.数组由于历史的原因也支持协变/逆变.在 C# 中,协变和逆变能够实现数组类型.委托类型和泛型类型参数的隐式引用转换. 协变保留分配兼容性,逆变则与之相反.协变允许方法具有的返回类型比接口的泛型类型参数定义的返回类型的派…
我们知道子类转换到父类,在C#中是能够隐式转换的.这种子类到父类的转换就是协变. 而另外一种类似于父类转向子类的变换,可以简单的理解为“逆变”. 上面对逆变的简单理解有些牵强,因为协变和逆变只能针对接口和代理类型.而父类和子类之间不存在这种逆变的概念. 协变和逆变的本质都是子类安全的转到父类的过程. 下面就来加深下印象,先定义两个类Car和Baoma public class Car { } public class Baoma : Car { } 明显Baoma(宝马)是Car的子类 1,先来…
需求:泛型使用多态性 备注:协变逆变只能修饰 接口和委托 简单理解: 1.使用 in 修饰后为逆变,只能用作形参使用 ,参考 public delegate void Action<in T>(T obj); 2.使用 out 修饰后为协变,只能用于返回值,参考 public delegate TResult Func<out TResult>(); 其他资料链接:http://www.cnblogs.com/LoveJenny/archive/2012/03/13/2392747…
Java作为面向对象的典型语言,相比于C++而言,对类的继承和派生有着更简洁的设计(比如单根继承). 在继承派生的过程中,是符合Liskov替换原则(LSP)的.LSP总结起来,就一句话: 所有引用基类(父类)的地方必须能够透明地使用其子类的对象. LSP包含四层含义: ① 子类完全拥有父类的方法,且具体子类必须实现父类的抽象方法: ② 子类中可以增加自己的方法: ③ 当子类覆盖或实现父类的方法时,方法的形参要比父类方法的更加宽松: ④ 当子类覆盖或实现父类的方法时,方法的返回值要比父类方法的更…
什么叫做协变(covariance)和逆变(contravariance)? 在变成语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数,泛型,返回值)替换或交换的特性,简单的说,协变是用一个窄类型替换宽类型,而逆变则是用宽类型覆盖窄类型. 协变:宽类型------>窄类型 逆变:窄类型------>宽类型 class Base{ public Number doStuff(){ return 0; } } class Sub extends Base{ @Override pu…
脑图概览 泛型声明和使用 协变和逆变 <C#权威指南>上在委托篇中这样定义: 协变:委托方法的返回值类型直接或者间接地继承自委托前面的返回值类型; 逆变:委托签名中的参数类型继承自委托方法的参数类型: 在泛型篇中这样定义: 协变:泛型参数定义的类型只能作为方法的返回类型,不能作为方法的参数类型,且该类型直接或者间接地继承自接口方法的返回值类型;可以使用out关键字声明协变参数. 逆变:泛型参数定义的类型只能作为方法参数的类型,不能作为返回值类型,且该类型是接口方法的参数类型的基类型:可以使用i…
看下面一段代码 Number num = new Integer(1); ArrayList<Number> list = new ArrayList<Integer>(); //type mismatch List<? extends Number> list = new ArrayList<Number>(); list.add(new Integer(1)); //error list.add(new Float(1.2f)); //error 有人会…
看下面一段代码 Number num = new Integer(1); ArrayList<Number> list = new ArrayList<Integer>(); //type mismatch List<? extends Number> list = new ArrayList<Number>(); list.add(new Integer(1)); //error list.add(new Float(1.2f)); //error 有人会…
协变,逆变与不变 能在使用父类型的场景中改用子类型的被称为协变. 能在使用子类型的场景中改用父类型的被称为逆变. 不能做到以上两点的被称为不变. 以上的场景通常包括数组,继承和泛型. 协变逆变与泛型(C#,Java) 在C#中,泛型参数的类型缺省是不变的,但是我们可以在定义泛型接口或委托时通过给参数类型加上out或in来标注该参数类型是协变还是逆变. 协变意味着你能把 IEnumerable<string> 用在需要 IEnumerable<object> 的地方. 这里 IEnu…
结论先行: PECS总结: 要从泛型类取数据时,用extends: 协变 要往泛型类写数据时,用super: 逆变 既要取又要写,就不用通配符(即extends与super都不用) 不变 List<?>是一个泛型,在没有赋值之前,表示它可以接受任何类型的集合赋值,赋值之后就不能往里面添加元素了. List<?>称为通配符集合.它可以接受任何类型的集合引用赋值,不能添加任何元素,但可以remove或clear,并非immutable集合.List<?>一般作为参数来接收外…
连载目录    [已更新最新开发文章,点击查看详细] 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型.泛型类型参数支持协变和逆变,可在分配和使用泛型类型方面提供更大的灵活性. 在引用类型系统时,协变.逆变和不变性具有如下定义. 这些示例假定一个名为 Base 的基类和一个名为 Derived的派生类. Covariance 使你能够使用比原始指定的类型派生程度更大的类型. 你可以向 IE…
转自:http://www.cnblogs.com/jingzhongliumei/archive/2012/07/02/2573149.html 先做点准备工作,定义两个类:Animal类和其子类Dog类,一个泛型接口IMyInterface<T>, 他们的定义如下:   public class Animal { } public class Dog : Animal { } interface IMyInterface<T> {  }   一.  协变和逆变的定义 从.Net…
先做点准备工作,定义两个类:Animal类和其子类Dog类,一个泛型接口IMyInterface<T>, 他们的定义如下:   public class Animal { } public class Dog : Animal { } interface IMyInterface<T> {  }   一.  协变和逆变的定义 从.Net Framework 4.0开始引入了一个新特性:协变与逆变,有人翻译为协变和反变,他们实际上所指的就是不同类型之间的一种转变(Variance).…
Scala中的协变,逆变,上界,下界等 目录 [−] Java中的协变和逆变 Scala的协变 Scala的逆变 下界lower bounds 上界upper bounds 综合协变,逆变,上界,下界 View Bound <% Context Bound 参考文档 Scala中的协变逆变和Java中的协变逆变不一样,看起来更复杂. 本文对Scala中的这些概念做一总结.首先看几个概念: covariant 协变.使你能够使用比原始指定的类型的子类 Contravariance 逆变.使你能够使…
http://blog.csdn.net/aladdinty/article/details/3486532 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 泛型 { class 泛型接口 { public static void Main() { PersonManager man = new PersonManager(); Person per =…
在net中json序列化与反序列化   准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则: 数据在键值对中 数据由逗号分隔 花括号保存对象 方括号保存数组 一.JSON的表现形式 在javascript中对象的表现形式如下 1.对象表现形式: <script type="text/javascript"> var jsonObject={code:0,result…
前言 本篇继续讲解泛型.上一篇讲解了泛型类的定义细节.本篇继续讲解泛型接口. 泛型接口 使用泛型可定义接口,即在接口中定义的方法可以带泛型参数.然后由继承接口的类实现泛型方法.用法和继承泛型类基本没有区别. 不变.协变和逆变 在.Net4.0之前,泛型接口是不变的..Net4.0通过协变和逆变为泛型接口和泛型委托增加了重要的扩展. 注:本书总体非常好,但在协变和逆变方面,我认为是有缺陷的.我一直偏好通过读书籍来了解技术,而不是逛论坛,但协变和逆变的问题我研究了本书多次,都没搞懂而放弃了,反正平时…
1. 基本概念 官方:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型.[MSDN] 公式:           协变:IFoo<父类> = IFoo<子类>:           逆变:IBar<子类> =  IBar<父类>: 暂时不理解没关系,您接着往下看. 2. 协变(Covariance) 1) out关键字 对于泛型类型参数,out 关键字…
1 泛型 1)如果我们要求函数的参数可以接受任意类型.可以使用泛型,这个类型可以代表任意的数据类型. 2)例如 List,在创建 List 时,可以传入整型.字符串.浮点数等等任意类型.那是因为 List 在 类定义时引用了泛型.比如在Java中:public interface List<E> extends Collection<E> Scala泛型应用案例1 1)编写一个Message类 2)可以构建Int类型的Message,String类型的Message. 3)要求使用…
前言 在引用类型系统时,协变.逆变和不变性具有如下定义. 这些示例假定一个名为 Base 的基类和一个名为 Derived的派生类. Covariance 使你能够使用比原始指定的类型派生程度更大的类型. 你可以将 IEnumerable 的实例分配给 IEnumerable 类型的变量. Contravariance 使你能够使用比原始指定的类型更泛型(派生程度更小)的类型. 你可以将 Action 的实例分配给 Action 类型的变量. Invariance 表示只能使用最初指定的类型.…
C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么?泛型的参数还能声明?对,如果有了参数的声明,则该泛型接口或者委托称为“变体”. List<汽车> 一群汽车 = new List<汽车>(); List<车子> 一群车子 = 一群汽车; 显然,上面那段代码是会报错的, 虽然汽车继承于车子,可以隐士转换为车子,但是List…
阿袁工作的第1天: 不变(Invariant), 协变(Covarinat), 逆变(Contravariant)的初次约 阿袁,早!开始工作吧. 阿袁在笔记上写下今天工作清单: 实现一个scala类ObjectHelper,带一个功能: 函数1:将一个对象转换成另一种类型的对象. 这个似乎是小菜一碟. 虽然不知道如何转换对象,那就定义一个函数参数,让外部把转换逻辑传进来.我真聪明啊! 这样,阿袁实现了第一个函数convert. class ObjectHelper[TInput, TOutpu…
官网:http://msdn.microsoft.com/zh-cn/library/dd799517.aspx 原文链接:http://book.51cto.com/art/201112/308570.htm 参考链接:http://www.cnblogs.com/yukaizhao/archive/2011/10/27/xiebian-nibian.html 1.3.4  泛型类型的协变(covariant)和逆变(contravariant) 在.NET 4.0之前的版本中,泛型类型是不支…
去年写过一篇博客谈了下我自己对协变和逆变的理解,现在回头看发现当时还是太过“肤浅”,根本没理解.不久前还写过一篇“黑”Java泛型的博客,猛一回头又是“肤浅”,今天学习Java泛型的时候又看到了协变和逆变,感觉又理解了点,记录一下,但不免还是“肤浅”,看了这篇博客的同学,欢迎留言交流下.Markdown 什么是协变和逆变? 到底什么是协变和逆变?先看例子: //Java Object[] objects = new String[2]; //C# object[] objects = new s…
C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么?泛型的参数还能声明?对,如果有了参数的声明,则该泛型接口或者委托称为“变体”. List<汽车> 一群汽车 = new List<汽车>(); List<车子> 一群车子 = 一群汽车; 显然,上面那段代码是会报错的, 虽然汽车继承于车子,可以隐士转换为车子,但是List…
博主之前也不是很清楚协变与逆变,今天在书上看到了有关于协变还是逆变的介绍感觉还是不太懂,后来看了一篇园子里面一位朋友的文章,顿时茅塞顿开.本文里面会有自己的一些见解也会引用博友的一些正文,希望通过本篇,能让大家对协变与逆变不再陌生. What's 协变逆变? 从字面理解协变就是"妥协的变化",而逆变则是"逆天的变化",哈哈,并不标准,我们来看看MSDN的解释: “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型. “逆变”则是指能够使用派生程度更小的类…
协变(Convariant)和逆变(Contravariant)的出现,使数组.委托.泛型类型的隐式转换变得可能. 子类转换成基类,称之为协变:基类转换成子类,称之为逆变..NET4.0以来,支持了泛型接口的协变和逆变. 泛型协变 如果子类泛型隐式转换成基类泛型,使用泛型协变. 有这样的2个基类和派生类. public class Animal { public virtual void Write() { Console.WriteLine("我是基类"); } } public c…
package javase; import java.util.ArrayList; import java.util.List; class Animal{ } class Cat extends Animal{ } public class CatIsAnimal { public static void main(String[] args){ Animal am = new Cat(); ArrayList<Cat> aam = new ArrayList<Cat>();…