从网上看到的比较不错的介绍委托

来源:互联网 发布:网络舆情监测应急预案 编辑:程序博客网 时间:2024/06/09 19:43
  “委托”,delegate,其实我觉得翻译成“代表”还好一点,它“代表”一个样子跟他差不多的方法。例如有以下方法:  
   
  private   int   DoSomething(string   s)   {...}  
   
  和以下委托(还是入乡随俗吧,我也叫委托好了):  
   
  public   delegate   int   DoThingsDelegate(string   s);  
   
  那么,因为样子差不多(术语叫“特征”(signature)相同——参数列表和返回值一样),这个委托就可以“代表”上面的方法。具体的“代表”的方法是:  
   
  private   DoThingsDelegate   varDoThingsDelegate;   //   定义委托变量  
  varDoThingsDelegate   =   new   DoThingsDelegate(DoSomething)   //   将方法与委托连接起来  
  int   returnValue   =   varDoThingsDelegate("hello!");   //   使用委托调用被代表的方法  
   
  以上三步缺一不可,但是第二步通常都不是我们自己做的——如果我们自己已经知道了方法名字,为什么不直接调用方法呢?我们通常都是1)定义委托,2)定义委托变量,3)让别人对委托变量赋值,4)把委托变量看成是个方法来调用。  
   
  这就推断出委托的使用场合:当我们要调用某个方法,但是我们只知道这个方法该长什么样子而不知道具体从哪里获得的时候,就是使用委托的时候。  
   
  .NET   里,有两个地方最常使用委托,首先就是事件,不过这个等下再说,然后就是异步调用方法。异步调用方法,简而言之,就是叫一个对象“开始”一项工作,但不需 要立刻返回结果,我也不等待结果,继续我自己的工作,到这个对象“完成”,可以返回结果的时候再“告诉我”。整个故事的难点就是“告诉我”——这个对象怎 么才能知道该怎么告诉我?为此,我在叫它“开始”工作的时候,顺便把我的一个方法包装成委托,告诉它“做完了之后,用这个方法告诉我”。这样,工作对象就 不需要知道我是谁/什么,完成工作之后尽管调用委托就行了。  
   
  事件摆在异步之后说,是因为事件是一种特殊的委托——可以“代表”多个同特征方法的委托。考虑以下场景:雇员wang有一个PlayGame事件,雇员 li交给wang一个委托,说“你玩游戏的时候告诉我”,然后雇员zhang也交给wang另一个委托:“你玩游戏的时候也告诉我”。那么,雇员wang 必须找个方法将所有玩游戏委托都记住,以便通知所有人,以免三缺一。这种“多播委托”(MulticastDelegate)是事件的基本模型,在事件发 生的时候由事件触发者通过调用委托来运行未知位置未知名字但已知特征的多个方法。  
   
  使用事件跟使用委托有一些区别。首先,符合委托特征的方法有了新名字:事件处理器(event   handler),因为它的作用就是处理一个事件。然后,将委托交给事件所有者这个动作叫做“订阅”(subscribe),也就是说事件像周刊一样,发 行的时候你就能收到一份。使用事件的步骤是  
   
  //1,   定义委托。该委托必须无返回(void),  
  //       因为事件如果存在多个订阅者,有返回值就乱套了。  
  //       委托类型的名字习惯用EventHandler或Handler结束,  
  //       因为这个委托类型代表的是事件处理器。  
  public   delegate   void   PlayGameEventHandler(Employee   starter,   string   gameName);  
  //   public   delegate   void   委托类型名(参数列表);  
   
  //2,在对象里定义事件,即“委托变量”——多播委托变量  
  public   event   PlayGameEventHandler   PlayGame;  
  //   public   event   委托类型名   事件名;  
   
  //3,由其他对象操作,订阅事件  
  wang.PlayGame   +=   new   PlayGameEventHandler(this.wang_PlayGame);  
  //   取消订阅只需要将上面的   +=   改成   -=  
   
  //   这个是事件处理器的范例:  
  private   void   wang_PlayGame(Employee   starter,   string   gameName)  
  {   Console.Write("我也要玩"   +   gameName   +   "!!");   }  
   
  //4,事件发生时,调用所有订阅者的事件处理器:  
  if   (this.PlayGame   !=   null)   //   没有人订阅就会   ==   null  
          this.PlayGame(this,   "Tic   Tac   Toe");    
原创粉丝点击