C#笔记 -- 协变、逆变
协变
理解:在泛型和委托中, 让使用某个泛型参数A的类型可以用一个使用由A派生的泛型参数B的类型实例化,(小=> 大)如
// IEnumerable<Animal> 与 List<Dog> 之间无继承关系,但是不会报错,协变
// IEnumerable<out T>
IEnumerable<Animal> animals = new List<Dog>();
// 下行会报错 => List<Dog> 不继承 List<Animal> 类型, 无法类型转化
// List<T>
List<Animal> animals = new List<Dog>();
条件: 使用 泛型修饰符 out
, 并且只能用作返回类型,该泛型参数不能用作方法参数使用
逆变
理解: 在泛型和委托中, 让使用某个泛型参数A的类型可以用一个使用A父类级别的泛型参数B的类型实例化,(大=>小)如
// Action<Dog> 与 Action<Animal> 无继承关系,不报错无,逆变
// Action<in T>
Action<Dog> actionDog = new Action<Animal>(a => { Console.WriteLine("animal"); });
// 下行报错 => Func<Dog> 与 Func<Animal> 无继承关系,报错
// Func<Out TResult>
Func<Dog> actionDog1 = new Func<Animal>(() => new Dog());
条件:使用 泛型修饰符 in
, 并且只能被使用,或者作为方法参数,不能用作返回类型
总结
返回结果的协变性
使用类型的逆变性
参考资料
C#笔记 -- 协变、逆变的更多相关文章
- 解读经典《C#高级编程》最全泛型协变逆变解读 页127-131.章4
前言 本篇继续讲解泛型.上一篇讲解了泛型类的定义细节.本篇继续讲解泛型接口. 泛型接口 使用泛型可定义接口,即在接口中定义的方法可以带泛型参数.然后由继承接口的类实现泛型方法.用法和继承泛型类基本没有 ...
- C#中泛型方法与泛型接口 C#泛型接口 List<IAll> arssr = new List<IAll>(); interface IPerson<T> c# List<接口>小技巧 泛型接口协变逆变的几个问题
http://blog.csdn.net/aladdinty/article/details/3486532 using System; using System.Collections.Generi ...
- C#的in/out关键字与协变逆变
C#提供了一组关键字in&out,在泛型接口和泛型委托中,若不使用关键字修饰类型参数T,则该类型参数是不可变的(即不允许协变/逆变转换),若使用in修饰类型参数T,保证"只将T用于输 ...
- Programming In Scala笔记-第十九章、类型参数,协变逆变,上界下界
本章主要讲Scala中的类型参数化.本章主要分成三个部分,第一部分实现一个函数式队列的数据结构,第二部分实现该结构的内部细节,最后一个部分解释其中的关键知识点.接下来的实例中将该函数式队列命名为Que ...
- java协变逆变,PECS
public static void main(String[] args) { // Object <- Fruit <- Apple <- RedApple System.out ...
- 协变 & 逆变
都跟里氏替换原则有关. 协变:你可以用一个子类对象去替换相应的一个父类对象,这是完全符合里氏替换原则的,和协(谐)的变.如:用Swan替换Bird. 逆变:你可以用一个父类对象去替换相应的一个子类对象 ...
- C#核心语法讲解-泛型(详细讲解泛型方法、泛型类、泛型接口、泛型约束,了解协变逆变)
泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具 ...
- C#核心语法-泛型(详细讲解泛型方法、泛型类、泛型接口、泛型约束,了解协变逆变)
泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具 ...
- c#打包文件解压缩 C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法 一个简单例子理解C#的协变和逆变 对于过长字符串的大小比对
首先要引用一下类库:using Ionic.Zip;这个类库可以到网上下载. 下面对类库使用的封装方法: 得到指定的输入流的ZIP压缩流对象 /// <summary> /// 得到指定的 ...
- C# 协变out 、逆变 in
需求:泛型使用多态性 备注:协变逆变只能修饰 接口和委托 简单理解: 1.使用 in 修饰后为逆变,只能用作形参使用 ,参考 public delegate void Action<in T&g ...
随机推荐
- Java开发者必备十大学习网站
作为开发者来说,必备的除了对编码的热情还要有自己的一套技巧,另外不可缺少的就是平时学习的网站.以下本人收集的Java开发者必备的网站,这些网站可以提供信息,以及一些很棒的讲座, 还能解答一般问题.面试 ...
- Java反射在整个程序运行中的位置
①java的核心机制 java有两种核心机制:java虚拟机(JavaVirtual Machine)与垃圾收集机制(Garbage collection): ①Java虚拟机:是运行所有Java程序 ...
- Hive环境安装
说明: (Hbase依赖于Hadoop,同时需要把元数据存放在mysql中),mysql自行安装 Hadoop2.0安装参考我的博客: https://www.cnblogs.com/654wangz ...
- Ubuntu server 安装的mysql数据库忘记密码的解决方法
客户端连接时报错MySQL数据库出现:Error 1045错误时,就表明输入的用户名或密码错误被拒绝访问了. 解决办法可以分为以下几步: 1.修改mysql配置文件,使得可以无密码登录mysql su ...
- Lucene.Net 3.0.3如何从TokenStream中获取token对象
Lucene.Net最高版本为3.0.3,并且apache已经不再提供Lucene.Net的更新,没仔细研究过Lucene.Net的所有版本,Lucene.Net3.0.3遍历TokenStream获 ...
- 详解Java中的clone方法 -- 原型模式
转自: http://blog.csdn.net/zhangjg_blog/article/details/18369201 Java中对象的创建 clone顾名思义就是复制, 在Java语言中, ...
- linq分析
例如: var sums = modellist .GroupBy(x => x.userId) .Select(group => new { Peo = group.Key, fist ...
- java压缩多个文件
首先创建一个工具类,定义好接口,这里的参数1:fileList:多个文件的path+name2: zipFileName:压缩后的文件名 下面是代码,注释已经很详细了 public class ZIP ...
- goquery常用语法
Find 查找获取当前匹配的每个元素的后代Eq 选择第几个Attr 获取对应的标签属性AttrOr 获取对应的标签属性.这个可以设置第二个参数.获取的默认值 如果获取不到默认调用对应默认值Each 遍 ...
- sqoop将mysql的tinyint类型转化为boolean类型
当mysql中的字段为tinyint类型时,通过sqoop导入数据到hdfs上,在hdfs上显示的是true,false值.为了显示0,1. 解决方法: jdbc:mysql://<hostna ...