首页 > 编程语言 >07c#协变逆变

07c#协变逆变

时间:2024-01-07 14:22:45浏览次数:22  
标签:07 c# Cat MyDelegate Animal 协变 new 合法

namespace 协变逆变
{
class Program
{
static void Main(string[] args)
{
//问题1:为什么会有协变逆变?
//首先,由里氏替换我们知道,子类可以安全的赋值给父类。
//(不熟悉可以会议六大设计原则//solid:
//s——单一职责
//o——开闭原则
//l——里氏替换
//I——接口隔离
//d——迪米特法则,依赖倒置原则)
Animal animal = new Cat();//合法
//其次,一定要知道, 协变逆变只是针对与泛型接口与泛型委托而言的。

        //生命两组正常的委托
        MyDelegate<Animal> myDelegate1 = new MyDelegate<Animal>((p) => { p.Eat(); return new Animal(); });//合法
        MyDelegate<Cat> myDelegate2 = new MyDelegate<Cat>((p) => { p.Miao(); return new Cat(); });//合法

        MyDelegate<Animal> myDelegate3 = new MyDelegate<Cat>((p) => { p.Miao(); return new Cat(); });//非法。
        //试想一下:如果合法了,那么 myDelegate3(new Animal()),参数对象animal,根本没有Miao()方法,编译器会出错的。
        MyDelegate<Cat> myDelegate4 = new MyDelegate<Animal>(() => { return new Animal(); });//非法。
         //同样试想一下:如果合法了,那么返回一个Animal类型,实际需要的是Cat类型,上层调用Miao()方法,编译器仍会出错的。                                                                                              
         //本质原因是,虽然Animal与Cat有继承关系,但是, MyDelegate<Animal>与 MyDelegate<Cat>并无继承关系。
           //我们希望是合法的,并且实际中也符合逻辑。所以框架开发者为这一目的,提出了协变的概念。如下
        MyDelegateOut<Animal> myDelegate5 = new MyDelegateOut<Cat>(() => {  return new Cat(); });//合法
        //返回子类类型赋值给父类类型合法。这其实就是支持协变,通过out参数
        MyDelegateOut<Cat> myDelegate6 = new MyDelegateOut<Animal>(() => { return new Animal(); });//非法。
        //返回父类类型赋值给子类类型不合法

        MyDelegateIn<Cat> myDelegateIn7 = new MyDelegateIn<Animal>((p) => { p.Eat(); });
        //需要传递父类的地方给一个子类,完全合法,这就是支持逆变。
        MyDelegateIn<Animal> myDelegateIn8 = new MyDelegateIn<Cat>((p) => { p.Miao(); });
        //需要传递子类的地方给一个父类,不合法,父类根本没有miao() 方法提供。

    }
}
class Animal
{
    public void Eat()
    {
        Console.WriteLine("吃");
    }
}
class Cat : Animal
{
    public void Miao()
    {
        Console.WriteLine("喵");
    }
}
delegate T MyDelegate<T>(T t);//普通委托
delegate void MyDelegateIn<in T>(T t);//支持逆变
delegate T MyDelegateOut<out T>();//支持协变

}

标签:07,c#,Cat,MyDelegate,Animal,协变,new,合法
From: https://www.cnblogs.com/cxfeng92/p/17950511

相关文章

  • Docker 入门-常用命令
    dockerpull用于从远程镜像仓库(比如DockerHub)拉取镜像的命令。基本语法是dockerpull[选项][镜像名称]:[标签]。例如,dockerpullnginx:latest将会从DockerHub拉取名为nginx的镜像,使用latest标签。如果不指定标签,默认会拉取latest标签的镜像。当然,也可以指定镜像仓......
  • 求实创新 不断探索 浙江移动基于亚信科技AntDB数据库率先完成CRM系统全域改造
    12日20日,中国信息通信研究院(简称:信通院)和中国通信标准化协会大数据库技术推进委员会(CCSATC601)共同组织的2023年大数据库“星河(Galaxy)”案例评选结果发布。中国移动通信集团浙江有限公司(以下简称:浙江移动)与亚信科技(中国)有限公司(简称:亚信科技)、湖南亚信安慧有限公司公司联合申报的《......
  • AntDB设计之CheckPoint——引言与功能简述
    1.引言数据库服务能力提升是一项系统性的工程,在不同的应用场景下,用户对于数据库各项能力的关注点也不同,如:读写延迟、吞吐量、扩展性、可靠性、可用性等等。国内不少数据库系统通过系统架构优化、硬件设备升级等方式,来解决性能的问题,但随着集群规模的逐渐扩大,对系统健壮性的要求也越......
  • AntDB设计之CheckPoint——设计实现
    3.设计实现下文介绍CheckPoint是如何实现其设计目标以及设计要求的。1.不影响业务CheckPoint在执行过程中,不能阻塞数据库服务的正常访问。这意味着在CheckPoint的过程中,数据是一直在发生变化的。为了不阻塞对数据的修改,保障导出数据的一致性,我们在此引入CheckPoint状态和表缓存来解......
  • 微软重定义键盘 将在键盘中植入Copilot键
    大家好,我是极智视界,欢迎关注我的公众号,获取我的更多前沿科技分享这篇其实大基调偏吐槽~先上图,Copilot其实就是微软AIGC的集大成者以及对外的统一接口,直接在键盘中"植入"Copilot键看起来是让"直通微软Copilot"更加便捷。从键盘本身来说,Copilot键肯定是很具微软特色,或者......
  • 无涯教程-Redis - INCRBY命令函数
    RedisINCRBY命令用于将键上存储的数字增加指定的值,如果键(key)不存在,则在执行操作之前将其设置为0,如果键包含错误类型的值或包含不能表示为整数的字符串,则返回错误。INCRBY-返回值整数回复,递增后的键值。INCRBY-语法以下是RedisINCRBY命令的基本语法。redis127.0......
  • DC电源模块的可持续发展与环境保护
    BOSHIDA DC电源模块的可持续发展与环境保护DC电源模块的可持续发展与环境保护是一个重要议题。DC电源模块是一种能够将交流电转换为直流电的设备,广泛应用于各种电子设备和系统中。然而,传统的DC电源模块存在一些环境问题,如能源浪费和电磁辐射。为了推动可持续发展和环境保护,需要采......
  • DC电源模块的应用范围与市场前景
    DC电源模块的应用范围与市场前景DC电源模块广泛应用于各种电子设备和系统中,包括通信设备、计算机、工业自动化设备、医疗设备、航天航空设备、新能源设备等。它们为这些设备提供稳定的直流电源,保证设备的正常运行。DC电源模块主要用于为电子设备提供稳定的直流电源,其应用范围非常广......
  • DC电源模块有哪些常见的故障和维修方法?
    BOSHIDADC电源模块有哪些常见的故障和维修方法?DC电源模块的常见故障和维修方法有以下几种:1.输出电压不稳定或无输出:可能原因包括变压器故障、输出端电容损坏、稳压管或稳压器件损坏等。修复方法包括更换损坏的元件、修复或更换变压器等。2.输出电压过高或过低:可能原因包括稳压管......
  • RocketMQ系统性学习-RocketMQ原理分析之消息的可靠性以及有序性如何保证
    欢迎关注公众号:【11来了】发送“资料”可以下载Redis、JVM系列文章PDF版本!作者为在读研究生,目前研二,计划在公众号记录学习常用中间件笔记,以及明年更新面试经历!消息的可靠性如何保证?要保证消息的可靠性,先来思考一下从哪些方面保证呢?这要看消息的生命周期,既然保证可靠性,那么就是......