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有两个重载版本而已,自己的想法,错的请大牛们指正,小弟不胜感激。

  请斧正。

 

posted on 2014-12-29 23:11  a2htray  阅读(1823)  评论(7编辑  收藏  举报

导航