一、协变

C#协变是指在一些特定的情况下,可以将一个派生类型的实例赋值给其基类或接口类型的引用。这里的“派生类型”指的是从某个基类或接口继承并增加了新的成员的类型。

C# 4.0 引入了对协变和逆变的支持。其中,协变针对的是返回类型,逆变则针对参数类型。通过使用协变和逆变,可以使得某些代码更加简单、易读,并且减少需要编写的重复代码。

具体来说,协变的主要提升体现在以下方面:

  1. 委托类型的协变:在 C# 2.0 中,委托类型必须完全匹配,也就是说,委托类型的参数和返回类型必须与目标方法的参数和返回类型完全相同。但在 C# 3.0 中,引入了委托类型的协变功能,可以将一个返回类型为派生类型的方法赋值给一个返回类型为基类类型(或接口类型)的委托变量,这样可以避免显式地进行类型转换。例如:

    public delegate T MyDelegate<out T>();
    public class Animal { }
    public class Mammal : Animal { }
    public class Giraffe : Mammal { } // 协变: Giraffe 是 Mammal 的派生类, Mammal 是 Animal 的派生类
    MyDelegate<Giraffe> giraffe = () => new Giraffe();
    MyDelegate<Mammal> mammal = giraffe;
    MyDelegate<Animal> animal = giraffe;
  2. 泛型类型参数的协变:在 C# 4.0 中,可以使用 out 关键字来声明泛型接口或委托的类型参数是协变的。这样,就可以将一个泛型类型的实例赋值给其基类或接口类型的引用。例如:

    public interface IMyInterface<out T> { }
    public class Animal { }
    public class Mammal : Animal { } // 协变: Mammal 是 Animal 的派生类
    IMyInterface<Mammal> mammal = null;
    IMyInterface<Animal> animal = mammal;

总之,C#的协变功能使得代码更加简洁、清晰,并且提高了代码的可读性和可维护性。

二、逆变

C#逆变是指在一些特定的情况下,可以将一个基类或接口类型的引用赋值给其派生类型的实例。这里的“派生类型”指的是从某个基类或接口继承并增加了新的成员的类型。

C# 4.0 引入了对协变和逆变的支持。其中,协变针对的是返回类型,逆变则针对参数类型。通过使用协变和逆变,可以使得某些代码更加简单、易读,并且减少需要编写的重复代码。

具体来说,逆变的主要应用场景是:

  1. 委托类型的逆变:在 C# 2.0 中,委托类型必须完全匹配,也就是说,委托类型的参数和返回类型必须与目标方法的参数和返回类型完全相同。但在 C# 4.0 中,引入了委托类型的逆变功能,可以将一个接受基类类型(或接口类型)参数的方法赋值给一个接受派生类型参数的委托变量,这样可以避免显式地进行类型转换。例如:

    public delegate void MyDelegate<in T>(T arg);
    public class Animal { }
    public class Mammal : Animal { }
    public class Giraffe : Mammal { } // 逆变: Animal 是 Mammal 的基类, Mammal 是 Giraffe 的基类
    MyDelegate<Animal> animal = (a) => Console.WriteLine(a.GetType());
    MyDelegate<Mammal> mammal = animal;
    MyDelegate<Giraffe> giraffe = animal;
  2. 泛型接口类型参数的逆变:在 C# 4.0 中,可以使用 in 关键字来声明泛型接口的类型参数是逆变的。这样,就可以将一个基类或接口类型的引用赋值给其派生类型的实例。例如:

    public interface IMyInterface<in T> { }
    public class Animal { }
    public class Mammal : Animal { } // 逆变: Animal 是 Mammal 的基类
    IMyInterface<Animal> animal = null;
    IMyInterface<Mammal> mammal = animal;

总之,C#的逆变功能使得代码更加简洁、清晰,并且提高了代码的可读性和可维护性。

《c#高级编程》第4章C#4.0中的更改(八)——协变和逆变的更多相关文章

  1. javascript高级编程3第二章:在html中使用javascript

    2.1 <script>元素 向html页面中插入javascript的主要方法,就是使用<script>元素.这个元素被加入到正式的html规范中.html4.01为< ...

  2. ASP.NET MVC5 高级编程 第5章 表单和HTML辅助方法

    参考资料<ASP.NET MVC5 高级编程>第5版 第5章 表单和HTML辅助方法 5.1 表单的使用 5.1.1 action 和 method 特性 默认情况下,表单发送的是 HTT ...

  3. ASP.NET MVC5 高级编程 第3章 视图

    参考资料<ASP.NET MVC5 高级编程>第5版 第3章 视图 3.1 视图的作用 视图的职责是向用户提供界面. 不像基于文件的框架,ASP.NET Web Forms 和PHP ,视 ...

  4. ASP.NET MVC5 高级编程 第2章 控制器

    参考资料<ASP.NET MVC5 高级编程>第5版 第2章 控制器 控制器:响应用户的HTTP 请求,并将处理的信息返回给浏览器. 2.1 ASP.NET MVC 简介 MVC 模式中的 ...

  5. UNIX环境高级编程 第8章 进程控制

    本章是UNIX系统中进程控制原语,包括进程创建.执行新程序.进程终止,另外还会对进程的属性加以说明,包括进程ID.实际/有效用户ID. 进程标识 每个进程某一时刻在系统中都是独一无二的,它们之间是用一 ...

  6. 【读书笔记】C#高级编程 第五章 泛型

    (一)泛型概述 泛型不仅是C#编程语言的一部分,而且与程序集中的IL代码紧密地集成.泛型不仅是C#语言的一种结构,而且是CLR定义的.有了泛型就可以创建独立于被包含类型的类和方法了. 1.性能 泛型的 ...

  7. 【读书笔记】C#高级编程 第六章 数组

    (一)同一类型和不同类型的多个对象 如果需要使用同一类型的多个对象,就可以使用数组或集合(后面章讲). 如果需要使用不同类型的多个对象,可以使用Tuple(元组)类型. (二)简单数组 如果需要使用同 ...

  8. 第四章 在MVC4.0中对脚本以及样式表的引用变化

    原文:http://www.cnblogs.com/xdotnet/archive/2012/07/21/aspnet40_webpage20.html 一.可以直接使用“~”,而无需使用Href对象 ...

  9. C#高级编程第1章-.NET体系结构

    内容提要: (1)编译和运行面向对象.NET代码 (2)IL/MSIL(Microsoft Intermediate Language)中间语言的优点 (3)值类型与引用类型 (4)数据类型化 (5) ...

  10. C#高级编程第2章-核心C#

    内容提要: 声明变量:变量的初始化和作用域:C#的预定义数据类型:在C#程序中使用条件语句.循环和跳转语句指定执行流:枚举:名称空间: Main()方法:基本命令行C#编译器选项:使用System.C ...

随机推荐

  1. 序列图 时序图 PlantUML vscode drawio 制作

    序列图 时序图 PlantUML vscode drawio 制作 需求 最近发现 序列图 很多文档都用到,而且很好用.经过研究用vscode,idea都可以编写.这里用vscode编写比较简单. d ...

  2. npm 添加 淘宝代理

    npm config set registry https://registry.npm.taobao.org

  3. 表单验证 validate 两种 一种是callback配合外部变量,当同步用。第2中是 then async await 这种 真正$api也适用

    validateFormRealProcessLeft () { let ret = false this.$refs.xxx.validate((valid) => { if (valid) ...

  4. C#之winform捕获Console.WriteLine内容到日志文件

    问题描述 之前接手同事的项目,是一个类似于服务端后台的Winform程序,主界面隐藏起来,只再任务栏显示程序图标. 整个项目里面没有日志记录功能,全靠Console.WriteLine打印信息.自己调 ...

  5. rancher添加用户报错x509: certificate has expired Internal error occurred: failed calling webhook "rancherauth.cattle.io":

    错误信息: Internal error occurred: failed calling webhook "rancherauth.cattle.io": Post https: ...

  6. Window10系统通过软件切换扬声器与耳机的音源输出

    原文地址: Window10系统通过软件切换扬声器与耳机的音源输出 - Stars-One的杂货小窝 个人平常一般使用扬声器,但有时候直播或和别人打游戏的时候,可能会带上耳机 目前的情况就是手动去插播 ...

  7. 09_使用SDL播放PCM

    通过命令ffpay播放PCM 可以使用ffplay播放<08_音频录制02_编程>中录制好的PCM文件,测试一下是否录制成功. 播放PCM需要指定相关参数: ar:采样率 ac:声道数 f ...

  8. 【3D可视化】3D可视化在智慧园区的应用

    随着5G运用和新基建政策,构建智慧城市系统成为当下城市管理的热门需求,智慧园区建设的核心是3D可视化平台,利用它可以提高企业园区智能化.3D数字化管理服务水平. 一.智慧园区概念 "3D可视 ...

  9. 文旅新体验!3DCAT助力广州非遗“元宇宙”街区炫酷亮相

    2022年6月12日,2022年"文化和自然遗产日"广州非遗宣传展示主会场暨广州非遗街区(北京路)开街仪式在南越王博物院(王宫展区)举行. 本次活动由广州市文化广电旅游局主办,广州 ...

  10. 三维模型3DTile格式轻量化在数据存储的重要性分析

    三维模型3DTile格式轻量化在数据存储的重要性分析 三维模型3DTile格式轻量化在数据存储中占有重要地位.随着科技的不断发展,尤其是空间信息科技的进步,人们对于三维地理空间数据的需求日益增长.然而 ...