一、协变

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. [MAUI] 混合开发概念

    ​ 混合开发的概念是相对与原生开发来说的:App不直接运行原生程序,而是在原生程序中运行一个Web程序,原生程序中包含Web运行时,用于承载Web页面.暂且将原生应用称之为Web容器,Web容器应该能 ...

  2. 异步小工具 asyncTool

    class asyncTool { constructor () { this.arr = [] this.ctx = {} } use (func) { const into = { func, n ...

  3. python的软连接的操作方法

    详细:切换python的版本 cd /usr/bin/ ls -l python* sudo rm -rf python sudo ln -s /usr/bin/python3.7 /usr/bin/ ...

  4. 基于python的固定间隔时间执行实例解析

    一 概念 datetime的用法如下: import datetime. # 打印当前时间 time1 = datetime.datetime.now() print(time1) # 打印按指定格式 ...

  5. 5分钟上手Python爬虫:从干饭开始,轻松掌握技巧

    很多人都听说过爬虫,我也不例外.曾看到别人编写的爬虫代码,虽然没有深入研究,但感觉非常强大.因此,今天我决定从零开始,花费仅5分钟学习入门爬虫技术,以后只需轻轻一爬就能查看所有感兴趣的网站内容.广告? ...

  6. 新闻新体验!3DCAT助力开启红网“元宇宙”新闻直播间

    2022年10月20日,湖南红网新媒体集团"华章·20--红网时刻新闻党的二十大报道云展厅"正式上线.深入到新闻元宇宙,开拓新的传播领域,这也是红网党政新媒体元宇宙传播应用实验室的 ...

  7. Python简单程序设计(Unicode编码与字符间转换篇)

    如题: (误以为本题存在两者之间互相转换,后附上逆过程代码) 解题方式如下: 逆过程:

  8. SpringBoot 常用注解总结

    核心注解 1. @SpringBootApplication 主要用于开启自动配置,它也是一个组合注解,主要组合了 @SpringBootConfiguration.@EnableAutoConfig ...

  9. C# 消息发送

    界面 frmMain using System; using System.Collections.Generic; using System.ComponentModel; using System ...

  10. Impala 高性能、低延迟的大数据查询引擎

    Impala是什么? Impala提供对大数据更快速,交互式 SQL查询. Impala支持对存储在HDFS.HBase及S3等数据查询. Impala使用和Hive相同的元数据.SQL定义.ODBC ...