c# 协变和逆变的理解】的更多相关文章

去年写过一篇博客谈了下我自己对协变和逆变的理解,现在回头看发现当时还是太过“肤浅”,根本没理解.不久前还写过一篇“黑”Java泛型的博客,猛一回头又是“肤浅”,今天学习Java泛型的时候又看到了协变和逆变,感觉又理解了点,记录一下,但不免还是“肤浅”,看了这篇博客的同学,欢迎留言交流下.Markdown 什么是协变和逆变? 到底什么是协变和逆变?先看例子: //Java Object[] objects = new String[2]; //C# object[] objects = new s…
1. 是什么 1.1 协变 协变指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型.如 string 到 object 的转换.多见于类型参数用作方法的返回值. 1.2 逆变 逆变指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型.如 object 到 string 的转换.多见于类型参数用作方法的输入值. 泛型类型参数支持协变和逆变,可在分配和使用泛型类型方面提供更大的灵活性. 2. 怎么理解 假如有一个 sub 子类和 parent 父类,我们可以很轻易地将 sub…
msdn 解释如下: “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型. “逆变”则是指能够使用派生程度更小的类型. 解释的很正确,大致就是这样,不过不够直白. 直白的理解: “协变”->”和谐的变”->”很自然的变化”->string->object :协变.  “逆变”->”逆常的变”->”不正常的变化”->object->string 逆变.  上面是个人对协变和逆变的理解,比起记住那些派生,类型,原始指定,更大,更小之类的词语,个人认…
http://www.cnblogs.com/qixuejia/p/4383068.html 深入理解 C# 协变和逆变   msdn 解释如下: “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型. “逆变”则是指能够使用派生程度更小的类型. 解释的很正确,大致就是这样,不过不够直白. 直白的理解: “协变”->”和谐的变”->”很自然的变化”->string->object :协变.  “逆变”->”逆常的变”->”不正常的变化”->object…
  深入理解 C# 协变和逆变 msdn 解释如下: “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型. “逆变”则是指能够使用派生程度更小的类型. 解释的很正确,大致就是这样,不过不够直白. 直白的理解: “协变”->”和谐的变”->”很自然的变化”->string->object :协变.  “逆变”->”逆常的变”->”不正常的变化”->object->string 逆变.  上面是个人对协变和逆变的理解,比起记住那些派生,类型,原始指…
文章目录 函数的参数和返回值 可变类型的变异 在之前的文章中我们简单的介绍过scala中的协变和逆变,我们使用+ 来表示协变类型:使用-表示逆变类型:非转化类型不需要添加标记. 假如我们定义一个class C[+A] {} ,这里A的类型参数是协变的,这就意味着在方法需要参数是C[AnyRef]的时候,我们可以是用C[String]来代替. 同样的道理如果我们定义一个class C[-A] {}, 这里A的类型是逆变的,这就意味着在方法需要参数是C[String]的时候,我们可以用C[AnyRe…
1. 可变性的类型:协变性和逆变性 可变性是以一种类型安全的方式,将一个对象当做另一个对象来使用.如果不能将一个类型替换为另一个类型,那么这个类型就称之为:不变量.协变和逆变是两个相互对立的概念: 如果某个返回的类型可以由其派生类型替换,那么这个类型就是支持协变的 如果某个参数类型可以由其基类替换,那么这个类型就是支持逆变的. 2. C# 4.0对泛型可变性的支持 在C# 4.0之前,所有的泛型类型都是不变量--即不支持将一个泛型类型替换为另一个泛型类型,即使它们之间拥有继承关系,简而言之,在C…
阿袁工作的第1天: 不变(Invariant), 协变(Covarinat), 逆变(Contravariant)的初次约 阿袁,早!开始工作吧. 阿袁在笔记上写下今天工作清单: 实现一个scala类ObjectHelper,带一个功能: 函数1:将一个对象转换成另一种类型的对象. 这个似乎是小菜一碟. 虽然不知道如何转换对象,那就定义一个函数参数,让外部把转换逻辑传进来.我真聪明啊! 这样,阿袁实现了第一个函数convert. class ObjectHelper[TInput, TOutpu…
关于协变和逆变要从面向对象继承说起.继承关系是指子类和父类之间的关系:子类从父类继承,所以子类的实例也就是父类的实例.比如说Animal是父类,Dog是从Animal继承的子类:如果一个对象的类型是Dog,那么他必然是Animal. 协变逆变正是利用继承关系 对不同参数类型或返回值类型 的委托或者泛型接口之间做转变. 如果一个方法要接受Dog参数,那么另一个接受Animal参数的方法肯定也可以接受这个方法的参数,这是Animal向Dog方向的转变是逆变.如果一个方法要求的返回值是Animal,那…
博主之前也不是很清楚协变与逆变,今天在书上看到了有关于协变还是逆变的介绍感觉还是不太懂,后来看了一篇园子里面一位朋友的文章,顿时茅塞顿开.本文里面会有自己的一些见解也会引用博友的一些正文,希望通过本篇,能让大家对协变与逆变不再陌生. What's 协变逆变? 从字面理解协变就是"妥协的变化",而逆变则是"逆天的变化",哈哈,并不标准,我们来看看MSDN的解释: “协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型. “逆变”则是指能够使用派生程度更小的类…
Scala中的协变,逆变,上界,下界等 目录 [−] Java中的协变和逆变 Scala的协变 Scala的逆变 下界lower bounds 上界upper bounds 综合协变,逆变,上界,下界 View Bound <% Context Bound 参考文档 Scala中的协变逆变和Java中的协变逆变不一样,看起来更复杂. 本文对Scala中的这些概念做一总结.首先看几个概念: covariant 协变.使你能够使用比原始指定的类型的子类 Contravariance 逆变.使你能够使…
看过几篇说协变与逆变的博客,虽然都是正确无误的,但是感觉都没有说得清晰明了,没有切中要害.那么我也试着从我的理解角度来谈一谈协变与逆变吧. 什么是协变与逆变 MSDN的解释:https://msdn.microsoft.com/zh-cn/library/dd799517.aspx 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型.泛型类型参数支持协变和逆变,可在分配和使用泛型类型方面提供…
协变 理解:在泛型和委托中, 让使用某个泛型参数A的类型可以用一个使用由A派生的泛型参数B的类型实例化,(小=> 大)如 ​ // IEnumerable<Animal> 与 List<Dog> 之间无继承关系,但是不会报错,协变 // IEnumerable<out T> IEnumerable<Animal> animals = new List<Dog>(); // 下行会报错 => List<Dog> 不继承 Li…
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>();…
1. 可变性的类型:协变性和逆变性 可变性是以一种类型安全的方式,将一个对象当做另一个对象来使用.如果不能将一个类型替换为另一个类型,那么这个类型就称之为:不变量. 协变和逆变是两个相互对立的概念: 如果某个返回的类型可以由其派生类型替换,那么这个类型就是支持协变的 如果某个参数类型可以由其基类替换,那么这个类型就是支持逆变的. 2. C# 4.0对泛型可变性的支持 在C# 4.0之前,所有的泛型类型都是不变量——即不支持将一个泛型类型替换为另一个泛型类型,即使它们之间拥有继承关系,简而言之,在…
一.背景 要搞懂Java中的协办与逆变,不得不从继承说起,如果没有继承,协变与逆变也天然不存在了. 我们知道,在Java的世界中,存在继承机制.比如MochaCoffee类是Coffee类的派生类,那么我们可以在任何时候使用MochaCoffee类的引用去替换Coffee类的引用(重写函数时,形参必须与重写函数完全一致,这是一处列外),而不会引发编译错误(至于会不会引发程序功能错误,取决于代码是否符合里氏替换原则). 简而言之,如果B类是A类的派生类,那么B类的引用可以赋值给A类的引用. 赋值的…
一.背景 要搞懂Java中的协办与逆变,不得不从继承说起,如果没有继承,协变与逆变也天然不存在了. 我们知道,在Java的世界中,存在继承机制.比如MochaCoffee类是Coffee类的派生类,那么我们可以在任何时候使用MochaCoffee类的引用去替换Coffee类的引用(重写函数时,形参必须与重写函数完全一致,这是一处列外),而不会引发编译错误(至于会不会引发程序功能错误,取决于代码是否符合里氏替换原则). 简而言之,如果B类是A类的派生类,那么B类的引用可以赋值给A类的引用. 赋值的…
百度:委托中的协变和逆变. 百度:.net中的协变和逆变. 协变是从子类转为父类. 逆变是从父类到子类. 这样理解不一定严谨或者正确.需要具体看代码研究.…
作者:Mike Ash,原文链接,原文日期:2015-11-20译者:Cee:校对:千叶知风:定稿:numbbbbb 在现代的编程语言中,子类型(Subtypes)和超类型(Supertypes)已经成为了非常常见的一部分了.协变(Convariance)和逆变(Contravariance)则能告诉我们什么时候使用子类型或超类型会优于原来使用的类型.这在我们使用的大多数编程语言中非常的常见,但是很多开发者仍然对这些概念感到模糊不清.今天我们就来详细讨论一下. 子类型(Subtypes)和超类型…
在net中json序列化与反序列化   准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则: 数据在键值对中 数据由逗号分隔 花括号保存对象 方括号保存数组 一.JSON的表现形式 在javascript中对象的表现形式如下 1.对象表现形式: <script type="text/javascript"> var jsonObject={code:0,result…
1. 基本概念 官方:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型.[MSDN] 公式:           协变:IFoo<父类> = IFoo<子类>:           逆变:IBar<子类> =  IBar<父类>: 暂时不理解没关系,您接着往下看. 2. 协变(Covariance) 1) out关键字 对于泛型类型参数,out 关键字…
概念 协变和逆变来源于类型和类型之间的绑定,C#4.0开始在泛型的接口和委托上支持协变和逆变,不过在这个版本之前的委托也是支持协变和逆变的.比如数组就支持协变,但是这不是一个好的特性,这C#初期版本从java引入的一个特性,当时的设计者认为C#应该尽可能的像java的一些特性靠拢,因为java当时太火了. 如果有类型Parent和其子类Sub,那么Parent p=new Sub();这种的类型转换是安全的.如果有一种类型和Parent类型进行了绑定,比如说Parent[]数组,如果Sub[]到…
继续还是探究协变与逆变,在正式开始之前,先来对Kotlin和Java的协变与逆变进行一个对比: 1.Kotlin是声明处协变:而在Java中是在使用处协变: 如何理解,我们先来回顾一下在Java使用协变的写法: 很显然是在我们使用的时候进行协变的,而在Kotlin中: 2.Kotlin中的out关键字叫做variance annotation,因为它是在类型参数声明处所指定的,因此我们称之为声明处协变(declaration-site variance):而对Java来说则是使用处协变(use-…
在上一次https://www.cnblogs.com/webor2006/p/11234941.html中学习了数据类[data class]相关的知识,这次会学习关于泛型相关的东东,其中有关于泛型我经常不太理解的关于<? extends T>和<? super T>的使用方式,所以好好学习,天天向上. 密封类(sealed class): 关于这个类,我们在上一次学习中其实是提到过这个关键字,回忆一下: 所谓密封,就是将东东给包装起来,然后我们要使用只能使用包装好里面受限的东东…
关于协变和逆变要从面向对象继承说起.继承关系是指子类和父类之间的关系:子类从父类继承所以子类的实例也就是父类的实例.比如说Animal是父类,Dog是从Animal继承的子类:如果一个对象的类型是Dog,那么他必然是Animal. 协变逆变正是利用继承关系 对不同参数类型或返回值类型 的委托或者泛型接口之间做转变.我承认这句话很绕,如果你也觉得绕不妨往下看看. 如果一个方法要接受Dog参数,那么另一个接受Animal参数的方法肯定也可以接受这个方法的参数,这是Animal向Dog方向的转变是逆变…
原文地址 谈谈.Net中的协变和逆变 关于协变和逆变要从面向对象继承说起.继承关系是指子类和父类之间的关系:子类从父类继承所以子类的实例也就是父类的实例.比如说Animal是父类,Dog是从Animal继承的子类:如果一个对象的类型是Dog,那么他必然是Animal. 协变逆变正是利用继承关系 对不同参数类型或返回值类型 的委托或者泛型接口之间做转变.我承认这句话很绕,如果你也觉得绕不妨往下看看. 如果一个方法要接受Dog参数,那么另一个接受Animal参数的方法肯定也可以接受这个方法的参数,这…
脑图概览 泛型声明和使用 协变和逆变 <C#权威指南>上在委托篇中这样定义: 协变:委托方法的返回值类型直接或者间接地继承自委托前面的返回值类型; 逆变:委托签名中的参数类型继承自委托方法的参数类型: 在泛型篇中这样定义: 协变:泛型参数定义的类型只能作为方法的返回类型,不能作为方法的参数类型,且该类型直接或者间接地继承自接口方法的返回值类型;可以使用out关键字声明协变参数. 逆变:泛型参数定义的类型只能作为方法参数的类型,不能作为返回值类型,且该类型是接口方法的参数类型的基类型:可以使用i…
Java作为面向对象的典型语言,相比于C++而言,对类的继承和派生有着更简洁的设计(比如单根继承). 在继承派生的过程中,是符合Liskov替换原则(LSP)的.LSP总结起来,就一句话: 所有引用基类(父类)的地方必须能够透明地使用其子类的对象. LSP包含四层含义: ① 子类完全拥有父类的方法,且具体子类必须实现父类的抽象方法: ② 子类中可以增加自己的方法: ③ 当子类覆盖或实现父类的方法时,方法的形参要比父类方法的更加宽松: ④ 当子类覆盖或实现父类的方法时,方法的返回值要比父类方法的更…
泛型擦除 Java的泛型本质上不是真正的泛型,而是利用了类型擦除(type erasure),比如下面的代码就会出现错误: 报的错误是:both methods  have same erasure 原因是java在编译的时候会把泛型,上面的<String>和<Integer>都给擦除掉(其实并没有真正的被擦除,javap -l -p -v -c可以看到LocalVariableTypeTable 里面有方法参数类型的签名). 协变与逆变 理解了类型擦除有助于我们理解泛型的协变与逆…
为何引入协变.逆变 我们知道一个子类对象可以赋值给一个基类对象 Animal animal = new Animal(); Animal cat = new Cat(); 那如果是用在泛型里面能行嘛? List<Animal> animalsList = new List<Animal>();//pass List<Animal> CatsList = new List<Cat>();//error 一组猫难道不是一组动物吗?错,是因为这里List<A…