• 委托的协变和逆变


      在 Framework 2.0 出现之前,委托协变这个概念还没有出现。此时因为委托是安全类型,它们不遵守继承的基础规则。即会这下面的情况:Manager 虽然是 Worker 的子类,但 GetWorkerHander 委托不能直接绑定 GetManager 方法,因为在委托当中它们的返回值 Manager 与 Worker 被视为完全无关的两个类型。

     1      public class Worker
     2      {.......}
     3      public class Manager:Worker
     4      {.......}
     5  
     6       class Program
     7      {
     8          public delegate Worker GetWorkerHandler(int id);
     9          public delegate Manager GetManagerHandler(int id);
    10  
    11          public static Worker GetWorker(int id)
    12          {
    13              Worker worker = new Worker();
    14              ..............
    15              return worker;
    16          }
    17  
    18          public static Manager GetManager(int id)
    19          {
    20              Manager manager = new Manager();
    21              ..............
    22              return manager;
    23          }
    24  
    25          static void Main(string[] args)
    26          {
    27              GetWorkerHandler workerHandler = new GetWorkerHandler(GetWorker);
    28              var worker=workerHandler(1);
    29  
    30              GetManagerHandler managerHandler = new GetManagerHandler(GetManager);
    31              var manager = managerHandler(2);
    32              Console.ReadKey();
    33          }
    34      }

    自从Framework 2.0 面试以后,委托协变的概念就应运而生,此时委托可以按照传统的继承规则进行转换。即 GetWorkerHandler 委托可以直接绑定 GetManager 方法。

     1      public class Worker
     2      {.......}
     3      public class Manager:Worker
     4      {.......}
     5  
     6       class Program
     7      {
     8          public delegate Worker GetWorkerHandler(int id);
     9          //在 Framework2.0 以上,委托 GetWorkerHandler 可绑定 GetWorker 与 GetManager 两个方法
    10  
    11          public static Worker GetWorker(int id)
    12          {
    13              Worker worker = new Worker();
    14              return worker;
    15          }
    16  
    17          public static Manager GetManager(int id)
    18          {
    19              Manager manager = new Manager();
    20              return manager;
    21          }
    22  
    23         static void Main(string[] args)
    24         {
    25             GetWorkerHandler workerHandler = new GetWorkerHandler(GetWorker);
    26             Worker worker=workerHandler(1);
    27             GetWorkerHandler managerHandler = new GetWorkerHandler(GetManager);
    28             Manager manager = managerHandler(2) as Manager;
    29             Console.ReadKey();
    30         }
    31      }

    委托逆变,是指委托方法的参数同样可以接收 “继承” 这个传统规则。像下面的例子,以 object 为参数的委托,可以接受任何 object 子类的对象作为参数。最后可以在处理方法中使用 is 对输入数据的类型进行判断,分别处理对不同的类型的对象。

     1     class Program
     2     {
     3         public delegate void Handler(object obj);
     4 
     5         public static void GetMessage(object message)
     6         {
     7             if (message is string)
     8                 Console.WriteLine("His name is : " + message.ToString());
     9             if (message is int)
    10                 Console.WriteLine("His age is : " + message.ToString());
    11         }
    12 
    13         static void Main(string[] args)
    14         {
    15             Handler handler = new Handler(GetMessage);
    16             handler(29);
    17             Console.ReadKey();
    18         }
    19    }

    运行结果

    注意委托与其绑定方法的参数必须一至,即当 Handler 所输入的参数为 A 类型,其绑定方法 GetMessage 的参数也必须为 A 类或者 A 的父类 。相反,当绑定方法的参数为 A 的子类,系统也无法辨认。

    来源:http://www.cnblogs.com/zhangyanhai/archive/2013/10/09/3359240.html

  • 相关阅读:
    Echarts 中当y轴有负数时,让x轴下落在y轴最小值(转载)
    echarts中如何去掉柱状图的横线和竖线(转载)
    echarts 风向 风速曲线
    echarts legend.type scroll 显示问题;渲染错误
    css实现左侧固定宽度,右侧宽度自适应(转载)
    npm 如何查看一个包的版本信息?(转载)
    echart series areaStyle 颜色不显示
    Spark与Hadoop Shuffle对比
    hive中with...as...的用法
    [转]MyBatis
  • 原文地址:https://www.cnblogs.com/xuekai-to-sharp/p/3368303.html
Copyright © 2020-2023  润新知