zoukankan      html  css  js  c++  java
  • 编写高质量代码改善C#程序的157个建议——建议44:理解委托中的协变

    建议44:理解委托中的协变

    委托中的泛型变量天然是部分支持协变的。为什么是“部分支持协变”?看下面示例:

       class Program
        {
            public delegate T GetEmployeeHanlder<T>(string name);
    
            static void Main()
            {
                GetEmployeeHanlder<Employee> getAEmployee = GetAManager;
                Employee e = getAEmployee("Mike");
            }
    
            static Manager GetAManager(string name)
            {
                Console.WriteLine("我是经理: " + name);
                return new Manager() { Name = name };
            }
    
            static Employee GetAEmployee(string name)
            {
                Console.WriteLine("我是雇员: " + name);
                return new Employee() { Name = name };
            }
    
        }
    
        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
        {
        }

    上中的GetAManager返回的是一个Manager,但是在使用中,其实是将其赋值给一个泛型参数为Employee的委托变量。因为存在下面一种情况,所以编译不过:

                GetEmployeeHanlder<Manager> getAManager = GetAManager;
                GetEmployeeHanlder<Employee> getAEmployee = GetAManager;

    要让上面的代码编译通过,同样需要为委托中的泛型参数指定out关键字:

    public delegate T GetEmployeeHanlder<out T>(string name);

    除非考虑到该委托声明肯定不会用于可变性,否则,为委托中的泛型参数指定out关键字将会拓展委托的应用,建议在实际编码过程中永远这样使用。实际上,FCL4.0中的一些委托声明已经用out关键字来让委托支持协变了,如我们常常会使用到的:

    public delegate TResult Func<out TResult>();
    
    public delegate TOutput Converter<in TInput, out TOutput>(TInput input);

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

  • 相关阅读:
    C#虚方法
    C#构造方法--实例化类时初始化的方法
    C#抽象类与抽象方法--就是类里面定义了函数而函数里面什么都没有做的类
    C#函数重载
    C#继承
    C#中public与private与static
    FPGA按一下按键,对应端口输出单个脉冲
    MyBatis学习 之 五、MyBatis配置文件
    MyBatis学习 之 四、动态SQL语句
    MyBatis学习 之 三、SQL语句映射文件(2)增删改查、参数、缓存
  • 原文地址:https://www.cnblogs.com/jesselzj/p/4733207.html
Copyright © 2011-2022 走看看