zoukankan      html  css  js  c++  java
  • 09.C#委托转换和匿名方法(五章5.1-5.4)

      今天将书中看的,自己想的写出来,供大家参考,不足之处请指正。进入正题。

      在C#1中开发web form常常会遇到使用事件,为每个事件创建一个事件处理方法,在将方法赋予给事件中,会使用new EventHandler(),不同的事件有各种不同的EventHandler的派生类的实例,因为我这里使用的时Console App,原理是一样的,且看

    //定义一个委托
    delegate void Printer();
    
    static void Main(string[] args)
    {
        Printer p = new Printer(Print1);
        p += new Printer(Print2);
        p += new Printer(Print3);
        p.Invoke();
        Console.ReadKey();
    }
    
    static void Print1()
    {
        Console.WriteLine("print1");
    }
    
    static void Print2()
    {
        Console.WriteLine("print2");
    }
    
    static void Print3()
    {
        Console.WriteLine("print3");
    }

      可以看到每次给p委托一个方法时,都要new Printer(),参数为要传入的方法,可以想象在不同的委托时,要用代码显式地创建各种委托,过于繁琐。而在C#2中支持从方法组到一个兼容委托类型的隐式转换,自己想当然的理解为C++中的复制构造函数,如Printer p = Print1其实就是调用了new Printer(Print1),代码如下。

    1 Printer p = Print1;
    2 p += Print2;
    3 p += Print3;
    4 p.Invoke();

      Printer p = Print1调用了Printer类的构造函数,而+=操作应该是Printer类型重载了+操作,用于两个Printer类相加,而方法组实现隐式转换,Print2和Print3隐式转换为Printer类的实例,C#2这样的操作减少了代码的输入,且更为直观,如"我只是把一个方法给到了一个对象,让它帮我执行,我才不管你要让传什么样的类型"。

    1. 泛型委托的协变性
    2. 委托返回的逆变性

      对于第一点,可以理解为要给委托一个方法,用这个方法创建的委托可以是另一个委托的派生类,如所有事件处理的基类是EventHandler,当一个事件需要传入一个方法,则可以使用这个方法来创建一个从EventHandler中派生的类的实例,不用事件我不会用代码表示,请大牛告知

      对于第二点,委托定义返回类型中,如果返回类型有派生类,如在实现的方法中返回其派生类,则可以使用该方法创建委托。

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

      匿名方法,匿名方法使用delegate关键字,允许你指定一个内联委托实例的操作,匿名方法返回一个委托的实例。

      C#2中许多内建的泛型委托,如Action(T),Predicate<T>等等,则在实例化委托时可以使用匿名函数。如

    1 Action<int> a = delegate (int x) { Console.WriteLine(x); };
    2 Predicate<bool> b = delegate (bool x) { return x == true; };
    3 a.Invoke(1);
    4 b.Invoke(1 == 1);
    5 a(2);
    6 b(2 == 3);

      请注意匿名方法返回一个委托实例。如果只是单纯是只想处理一些无关于参数的事情,可以考虑省略参数。这让我想到一点就是在程序出错时,如果不记录参数,可以直接打印"出错了",而对于匿名函数,则可以省略参数。

    1 System.Threading.Thread th = new System.Threading.Thread(delegate (object x) { });
    2 System.Threading.Thread th2 = new System.Threading.Thread(delegate() { });

      其实上述的讲法是错的,其实很讨厌一些话,写了很多的东西,自己看得好像有点道理,然后突然告诉你"那些东西错误的观点",这次我也来使用一下。

      前面说过匿名函数返回一个委托的实例,我解理为匿名方法确实是一个方法,因为存在之前说过的隐式转换(也就是C++中的复制构造函数,或者单参数的构造函数),它返回一个符合new System.Threading.Thread()中一个合适的参数类型,所以我觉得参数是不可省略的,书中就是可以省略,其实只是System.Threading.Thread有两个重载版本而已,自己的想法,错的请大牛们指正,小弟不胜感激。

      请斧正。

  • 相关阅读:
    一套测试题
    静态成员与友元
    grids2742
    [转]CentOS添加第三方yum源
    Linux软件包管理
    类的基本概念
    2012百度实习生笔试题(c++方向)
    anyview 数据结构习题集 第1章答案
    Linux常用命令
    anyview 数据结构习题集 第2章答案
  • 原文地址:https://www.cnblogs.com/a2htray/p/4192610.html
Copyright © 2011-2022 走看看