zoukankan      html  css  js  c++  java
  • 编写高质量代码改善C#程序的157个建议——建议42:使用泛型参数兼容泛型接口的不可变性

    建议42:使用泛型参数兼容泛型接口的不可变性

    让返回值类型返回比声明的类型派生程度更大的类型,就是“协变”。如:

            public Employee GetAEmployee(string name)
            {
                Console.WriteLine("我是雇员:"+name);
                return new Programmer() { Name = name };//Programmer是Employee的子类
            }

    Programmer是Employee的子类,所以Programmer对象也是Employee对象。方法GetAEmployee返回一个Programmer的对象,也就是相当于返回一个Employee对象。

    由于协变是一种如此自然的应用,我们很可能写出如下代码:

        class Program
        {
            static void Main(string[] args)
            {
                ISalary<Programmer> s = new BaseSalaryCounter<Programmer>();
                PrintSalary(s);
            }
    
            static void PrintSalary(ISalary<Employee> s)
            {
                s.Pay();
            } } interface ISalary<T> { void Pay(); } class BaseSalaryCounter<T> : ISalary<T> { public void Pay() { Console.WriteLine("Pay base salary"); } } class Employee { public string Name { get; set; } } class Programmer : Employee { } class Manager : Employee { }

    在PrintSalary这个方法中,方法接收的类型是ISalary<Employee>。于是,我们想当然的认为ISalary<Programmer>必然也可以被PrintSalary方法接收的。事实却不然,代码编译会通不过:

    无法从“MyTest.ISalary<MyTest.Programmer>”转换为“MyTest.ISalary<MyTest.Employee>”

    编译器对于接口和委托类型参数的检查是非常严格的,除非用关键字out特别声明,不然这段代码只会编译失败。要让PrintSalary完成需求,我们可以使用泛型类型参数:

            static void PrintSalary<T>(ISalary<T> s)
            {
                s.Pay();
            }

    注意:建议开头指出“协变”是针对返回值而言的,但是所举的这个例子并没有体现“返回值”这个概念。实际上,只有泛型类型参数在一个接口声明中不被用来作为方法的输入参数,我们就姑且把它看成是“返回值”类型的。所以,本建议中这种模式是满足“协变”定义的。但是,只要将T作为输入参数,就不满足“协变”定义了。

    转自:《编写高质量代码改善C#程序的157个建议》陆敏技

  • 相关阅读:
    CSDN社区之星专訪:我的蜕变之路
    Linux中运行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory。
    00075_BigInteger
    Delphi中Interface接口的使用方法
    Delphi结构体的扩展,可以自动初始化,反初始化,自定义拷贝函数.
    关于指针和堆栈
    Delphi 中的 procedure of object
    MikroTik RouterOS防火墙与过滤详解
    用 ROS 做内网DNS服务器
    GR32 TImage32的图层绘制原理
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4733120.html
Copyright © 2011-2022 走看看