浅谈C# 中的委托和事件

2019-12-30 15:06:43丽君

输出为:

Morning, Jimmy Zhang
早上好, Jimmy Zhang
早上好, 张子阳

让我们再次对委托作个总结:

使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法。

事件的由来

我们继续思考上面的程序:上面的三个方法都定义在Programe类中,这样做是为了理解的方便,实际应用中,通常都是 GreetPeople 在一个类中,ChineseGreeting和 EnglishGreeting 在另外的类中。现在你已经对委托有了初步了解,是时候对上面的例子做个改进了。假设我们将GreetingPeople()放在一个叫GreetingManager的类中,那么新程序应该是这个样子的:


namespace Delegate {
   //定义委托,它定义了可以代表的方法的类型
  public delegate void GreetingDelegate(string name);
   
   //新建的GreetingManager类
  public class GreetingManager{
    public void GreetPeople(string name, GreetingDelegate MakeGreeting) {
      MakeGreeting(name);
    }
   }

   class Program {
    private static void EnglishGreeting(string name) {
      Console.WriteLine("Morning, " + name);
    }

    private static void ChineseGreeting(string name) {
      Console.WriteLine("早上好, " + name);
    }

    static void Main(string[] args) {
      // ... ...
     }
   }
 }

这个时候,如果要实现前面演示的输出效果,Main方法我想应该是这样的:


static void Main(string[] args) {
   GreetingManager gm = new GreetingManager();
   gm.GreetPeople("Jimmy Zhang", EnglishGreeting);
   gm.GreetPeople("张子阳", ChineseGreeting);
 }

我们运行这段代码,嗯,没有任何问题。程序一如预料地那样输出了:

Morning, Jimmy Zhang

早上好, 张子阳

现在,假设我们需要使用上一节学到的知识,将多个方法绑定到同一个委托变量,该如何做呢?让我们再次改写代码:


static void Main(string[] args) {
   GreetingManager gm = new GreetingManager();
   GreetingDelegate delegate1;
   delegate1 = EnglishGreeting;
   delegate1 += ChineseGreeting;

   gm.GreetPeople("Jimmy Zhang", delegate1);
 }

输出:

Morning, Jimmy Zhang
早上好, Jimmy Zhang

到了这里,我们不禁想到:面向对象设计,讲究的是对象的封装,既然可以声明委托类型的变量(在上例中是delegate1),我们何不将这个变量封装到 GreetManager类中?在这个类的客户端中使用不是更方便么?于是,我们改写GreetManager类,像这样:


public class GreetingManager{
   //在GreetingManager类的内部声明delegate1变量
  public GreetingDelegate delegate1; 

   public void GreetPeople(string name, GreetingDelegate MakeGreeting) {
    MakeGreeting(name);
   }
 }