• 编写高质量代码改善C#程序的157个建议——建议43:让接口中的泛型参数支持协变


    建议43:让接口中的泛型参数支持协变

    除了上一建议中提到的使用泛型参数兼容接口不可变性外,还有一种办法是为接口中的泛型声明加上out关键字来支持协变,如下所示:

        interface ISalary<out T>    //使用out关键字
        {
            void Pay();
        }
            static void Main(string[] args)
            {
                ISalary<Programmer> s = new BaseSalaryCounter<Programmer>();
                ISalary<Manager> t = new BaseSalaryCounter<Manager>();
                PrintSalary(s);
                PrintSalary(t);
            }
    
            static void PrintSalary(ISalary<Employee> s)    //用法正确
            {
                s.Pay();
            }

    这段代码在FCL4.0以前是不能编译通过的,因为IEnumerable<T>这个接口在FCL中没有被声明为IEnumerable<out T>:

            static void Main()
            {
                IList<Programmer> programmers = new List<Programmer>();
                IList<Manager> managers = new List<Manager>();
                PrintPersonName(programmers);
                PrintPersonName(managers);
            }
    
            static void PrintPersonName(IEnumerable<Employee> persons)
            {
                foreach (Employee person in persons)
                {
                    Console.WriteLine(person.Name);
                }
            }

    FCL4.0对很多接口进行了修改以支持协变,如IEnumerable<out T>、IEnumerator<out T>、IQuerable<out T>等。由于IEnumerable<out T>现在支持协变,所以上段代码在FCL4.0中能运行得很好。

    在我们自己的代码中,如果要编写泛型接口,除非确定该接口中的泛型参数不涉及变体,否则都建议加上out关键字。协变增大了接口的使用范围,而且几乎没有带来什么副作用。

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

  • 相关阅读:
    JavaScript实现上传图片预览[js前端实现]
    Java内存Happen-Before
    《干净架构读书笔记》——业务驱动编程
    《干净架构读书笔记》——编程范式
    Scrum中的冲刺和迭代
    Spring Cloud中通过Kafka传递自定义Header
    领域驱动开发(DDD)Web开发中的典型分层
    给开发团队减减负
    业务实体和用例
    什么是好的代码-代码Review要点
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4733165.html
Copyright © 2020-2023  润新知