C# 协变、逆变
微软官方概述:
在C#中,协变和逆变能够实现数组类型、委托类型和泛型类型参数的隐式引用转换。协变保留分配兼容性,逆变则与之相反。
协变:能够使用与原始指定的派生类型相比,派生程度更大的类型。
逆变:能够使用派生程度更小的类型。
官方示例:
string str = "test";
object obj = str;
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
static void SetObject(object){}
Action<object> actObject = SetObject;
Action<string> actString = actObject;
上面示例中,从 string --> object 的隐式转换这是协变;如果从 object --> string 转换这是逆变。
数组协变
string[] str = new string[10];
object[] array = str;
这是一种不安全的操作,在对 array数组赋值时,array[0] = 0; 在编译时可以通过,但是在运行时会提示错误。“System.ArrayTypeMismatchException:“尝试访问类型与数组不兼容的元素。””。这里的array 只是保存了str的引用,仍然是一个string类型的数组。
委托中的协变和逆变
对方法组的协变和逆变支持将方法签名与委托类型相匹配。这样不仅可以将具有匹配签名的方法分配给委托,还可以分配与委托类型指定的派生类型相比,返回派生程度更大的类型的方法(协变)或者如果方法所接受参数的派生类型所具有的程度小于委托类型指定的程度(逆变),也可将其分配给委托。这就包含泛型委托和非泛型委托。
class People {}
class Student:People{}
delegate People Method();
class Program
{
People peopleMethod(){}
Student studetnMethod(){}
static void Test(){
Method method = peopleMethod;
Method method2 = studentMethod;
}
}
上面的委托Method(),返回值类型是People,但是我们采用更加具体的student类型也是可以的,由student --> People类型的转换,这是正常的多态行为。委托的目标方法可能返回比委托声明的返回值类型更加特定的返回值类型,这称为协变。
那么当我们也可以采用一个比目标方法参数类型更加具体的参数类型,这称为逆变。
下面的示例:
delegate void StringAction (string s);
class Test{
static void Main(){
StringAction sa = new StringAction (ActionObject);
sa("hi");
}
static void ActionObject(object o) => Console.WriteLine(o);
}
C# 4.0添加了 out 和 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# 协变out 、逆变 in
需求:泛型使用多态性 备注:协变逆变只能修饰 接口和委托 简单理解: 1.使用 in 修饰后为逆变,只能用作形参使用 ,参考 public delegate void Action<in T&g ...
- 编写高质量代码改善C#程序的157个建议[协变和逆变]
前言 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html .本文主要学习记录以下内容: 建议42.使用泛型参数兼容泛型接口的不可变性 建议43.让接口 ...
随机推荐
- MySQL问题记录——ERROR 1728 (HY000)
MySQL问题记录——ERROR 1728 (HY000) 摘要:本文主要记录了在使用MySQL的过程中遇到错误代码为1728的问题以及解决方案. 问题重现 在创建自定义函数的时候,出现了问题: my ...
- idea的service注入mapper报错
一.问题 idea的java项目中,service类中注入mapper报错 二.解决 方法1 在mapper类上加上 @Repository 注解即可,当然不加也行,程序也不回报错,是idea的误报 ...
- css布局技巧
CSS用户界面样式 鼠标样式currsor li{ cursor:pointer: } 设置或检索在对象上移动鼠标指针采用何种系统预定义的光标形状 属性值 描述 default 默认 pointer ...
- 证券secuerity英语secuerity安全
中文名:证券 外文名:security.secuerity 类别:经济权益凭证统称 组成:资本证券.货币证券和商品证券 作用:用来证明持者权益的法律凭证 图集 目录 1 发展历程 ? 世界 ? 中国 ...
- 74HC238引脚定义 使用方法
三八译码器 用作IO扩展与复用 用3个IO,可以控制8个输出 引脚定义 A0~A2:3个输入 E1.E2:拉低使能,可以接地 E3:拉高使能,可以接VCC Y0~Y7:8个输出 真值表 如果想输出8个 ...
- jQuery-File-Upload $(...).fileupload is not a function $.widget is not a function
使用 jQuery-File-Upload 库的时候碰到了 $(...).fileupload is not a function 和 $.widget is not a function 问题. ...
- gradle使用基础
说明 介绍gradle使用基础,gradle基础脚本结构和常规使用方法,以及一个简单的gradle示例.主要是为了简单的介绍gradle使用. gradle环境配置 gradle可以通过两种方式运行g ...
- PHP配置篇(一)--php开启redis扩展
因为最近要用到Redis,下面记录下如何给PHP开启redis的扩展. 一.安装redis 1.安装redis:https://github.com/MSOpenTech/redis/releases ...
- JDOJ1100: Fix
题目大意 给你n个点,其中一些点是固定的,然后还有一些没有固定的,然后问你固定所有点所用的线段的最小长度是多少. 所谓固定,就是形如三角形的情况,就是两个固定的点向一个未固定的点连两条边,就能把未固定 ...
- 第十五周博客作业 <西北师范大学| 周安伟>
第十五周作业 助教博客链接https://home.cnblogs.com/u/zaw-315/ 作业要求链接https://www.cnblogs.com/nwnu-daizh/p/10946673 ...