天天学C#-委托(delegate)

类别:.NET开发 点击:0 评论:0 推荐:

参考资料

《C#技术揭密》

 http://www.microsoft.com/china/msdn/events/featureevents/default.mspx  这里有一些微软.net编程的视频资料

      对学过c/c++的来说,delegate就相当于函数指针,看下面的代码:

class Person

{

    public Person(string name)

    {

        this.name=name;

    }

    //一些属性和方法

    string name;

     public void Eat(Food food);

}

Person类有一个Eat方法,对它的实例来说,张三,李四,王五都有他们自己的Eat方法

Person zhanSan,liSi,wangWu;

zhanSan=new Person(”张三”);

liSi=new Person(”李四”);

wangWu=new Person(”王五”);

我们可以通过定义一个委托来分别调用Eat方法

public void delegate Eat(Food food);

如果想调用zhanSan.Eat(food)

Eat zhanSanEat=new Eat(zhanSan.Eat);

其他类似:

Eat liSiEat=new Eat(liSi.Eat);

Eat wangWu=new Eat(wangWu.Eat);

这样调用zhanSanEat(food)就相当于调用zhanSan.Eat(food)

委托最有用的是委托链,如果张三,李四,王五共同进餐

则可以定义委托如下

//定义复合委托

Eat togetherEat;

//c#中通过“+“将方法Connect到委托,即将委托加到委托链中

//通过“-”将方法从委托链中删除

togetherEat=zhanSanEat+liSiEat+wangwuEat;

//张三,李四,王五一起吃西瓜

togetherEat(西瓜);

//不带张三,只有李四和王五吃

togetherEat=liSiEat+wangWuEat;

togetherEat(西瓜);

.net中的事件机制就是通过委托来实现的。

下面是C#技术揭密上的一段源代码,我加了一些注释,讲解了事件的实现机制


//InventoryManager类用于更新库存量,它也定义了当更新库存量时应该触发的事件,也就是说它发布一个委托由订阅者调用
//InventoryWatcher类定义的是订阅者,可以选择是否将自己添加到发布者的列表中,从而在更新库存时,得到通知
using System;

namespace DelegateEvents
{
 //定义EventArgs的派生类,用来携带事件信息
 class InventoryChangeEventArgs:System.EventArgs
 {
  public InventoryChangeEventArgs(string sku,int change)
  {
   this.sku=sku;
   this.change= change;
  }
  string sku;
  public string Sku
  {
   get{return sku;}
  }
  int change;
  public int Change
  {
   get{return change;}
  }
 }
 //发布者
 class InventoryManager
 {
  //声明一个委托,两个参数必不可少,第一个是发布者对象,第二个一定要是EventArgs类或者其派生类
  public delegate void InventoryChangeEventHandler(object source,InventoryChangeEventArgs e);
  //定义该委托的事件实例(即委托链,用于订阅者将自己加到委托链中
  public event InventoryChangeEventHandler OnInventoryChangeHandler;
  //InventoryManager的方法,用于更新库存
  public void UpdateInventory(string sku,int change)
  {
   if(0==change)
    return;
   //定义事件参数实例,传递sku和change信息
   InventoryChangeEventArgs e=new InventoryChangeEventArgs(sku,change);
   //判断委托链表是否为空,如果不空,说明有订阅者订阅
   if(this.OnInventoryChangeHandler!=null)
   {
    Console.WriteLine("[InventoryManager.UpdateInventory] Raising event to all subscribers...\n");
    //依次调用委托链表上的方法
    this.OnInventoryChangeHandler(this,e);
   }
  }
 }
 //订阅者
 class InventoryWatcher
 {
  //定义发布者
  InventoryManager invnetoryManager;
  public InventoryWatcher(InventoryManager inventoryManager)
  {
   Console.WriteLine("[InventoryWatcher.InventoryWatcher] Subscribing to InventoryChange event\n");
   this.invnetoryManager=inventoryManager;
   //将自己Connect到InventoryManager.InventoryChangeEventHandler委托
   inventoryManager.OnInventoryChangeHandler+=new InventoryManager.InventoryChangeEventHandler(OnInventoryChange);
  }
  //订阅者的方法,用于在发布者更新库存量时调用
  void OnInventoryChange(object source,InventoryChangeEventArgs e)
  {
   int change=e.Change;
   Console.WriteLine("[InventoryManager.OnInventoryChange]\n\tPart'{0}' was {1} by {2} units\n",e.Sku,change>0?"increased":"decreased",Math.Abs(e.Change));
  }
 }
 /// <summary>
 /// 用委托实现事件机制实例
 /// </summary>
 class DelegateEvents
 {
  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [STAThread]
  static void Main(string[] args)
  {
   //定义委托发布者对象
   InventoryManager inventoryManager=new InventoryManager();
   
   Console.WriteLine("[DelegateEvents.Main Instantiating subscriber object\n");
   //定义订阅者对象
   InventoryWatcher inventWatcher=new InventoryWatcher(inventoryManager);
   inventoryManager.UpdateInventory("111 006 116",2);
   inventoryManager.UpdateInventory("111 005 383",5);

   Console.ReadLine();
  }
 }
}

以上只是自己的一点理解,很多地方都不成熟,可能举的例子也不恰当,欢迎指点,和大家共同学习

 

 

本文地址:http://com.8s8s.com/it/it42703.htm