C# 中的委托类似于 C 或 C++ 中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与 C 或 C++ 中的函数指针不同,委托是面向对象、类型安全的,并且是安全的。

委托声明定义一种类型,它用一组特定的参数以及返回类型封装方法。对于静态方法,委托对象封装要调用的方法。对于实例方法,委托对象同时封装一个实例和该实例上的一个方法。如果您有一个委托对象和一组适当的参数,则可以用这些参数调用该委托。

委托的一个有趣且有用的属性是,它不知道或不关心自己引用的对象的类。任何对象都可以;只是方法的参数类型和返回类型必须与委托的参数类型和返回类型相匹配。这使得委托完全适合“匿名”调用。

下面简单的用几行代码来说明一下

delegate void MyDelegate(int x);
class MyClass
 {
   public static void Method1(int i)
   {
    }

    public void Method2(int i)
   {  
    }

}
//声明的方法 method1 和method2 的参数必须和声明delegate 是一样才行。

 class TestClass
{
 static void Main()
 {
   //静态方法       
   MyDelegate delegate1=new MyDelegate(MyClass.Method1); //当代用delegate1时,就会自动调用method1这个方法

    //实例方法

     TestClass class1=new MyClass();

     MyDelegate delegate2=new MyDelegate(class1.Method2);

      //另一个委托
      MyDelegate delegate3=new MyDelegate(delegate2);

 }

}

下面我用一个简单的例子,更详细的讲解一下delegate的用法
public delegate void NotifyCallback(decimal balance)
public class DelegateAccount
{
   public static void NotifyCustomer(decimal balance)
   {
       Console.WriteLine("Dear customer,");
       Console.WriteLine("Account overdrawn, balance={0}", balance);
   }
   public static void NotifyBank(decimal balance)
   {
       Console.WriteLine("Dear bank,");
       Console.WriteLine("Account overdrawn, balance={0}", balance);
   }
   public static void NotifyInstance(decimal balance)
   {
       Console.WriteLine("Dear instance,");
       Console.WriteLine("Account overdrawn, balance={0}", balance);
   }
}

//上面这个class 定义了delegate 和要被调用的3个方法,每个方法的参数声明和delegate 的参数声明是一样的


public class Account
{
   private decimal balance;
   private NotifyCallback notifyDlg;
   public Account(decimal bal, NotifyCallback dlg)
   {
       this.balance=bal;
       this.notifyDlg=dlg;
   }
   public void SetDelegate(NotifyCallback dlg)
   {
       this.notifyDlg=dlg;
   }
   public void Deposit(decimal amount)
   {
       balance=balance+amount
   }
   public void Withdraw(decimal amount)
   {
      balance=balance-amount;
      if(balance<0)
     {
         notifyDlg(balance);
     }
    //如果balance 小于0,就调用delegate
   }
    public decimal Balance
   {
        get
            {
                  return balance;
            }
    }
   // 定义了一个属性balance,而且是只读的

//这个class定义了当取钱是,如果balance 小于0的时候,就会调用delegate



public class DDelegate
{
    public DDelegate()
    {
        NotifyCallback custDlg=new NotifyCallback(DelegateAccount.NotifyCustomer);//一个调用notifycustomer的delegate
        NotifyCallback bankDlg=new NotifyCallback(DelegateAccount.NotifyBank); //一个调用notifybank的delegate
    NotifyCallback currDlg=custDlg+bankDlg; //"+"表示currDlg被调用的时候,notifycustomer 和notifybank会被一起使用

       Account acc=new Account(100, currDlg);
       Console.WriteLine("balance={0}", acc.balance);
       acc.Withdraw(125);
      //因为取钱125,所以banlance<0了,这时就会调用currDlg这delegate,因为上面已经说了,如果调用currDlg,就会调用notifycustomer和notifybank这2个方法,所以这个时候,这2个方法就会被使用。
       Console.WriteLine("balance={0}", acc.balance);
       acc.Deposit(200);
       acc.Withdraw(150);
       Console.WriteLine("balance={0}", acc.balance);
       currDlg=currDlg-bankDlg;
       acc.SetDelegate(currDlg);
       acc.Withdraw(125);
      
      DelegateAccount ds=new DelegateAccount();
      NotifyCallback instDlg=new NotifyCallback(ds.NotifyInstance);
      currDlg=currDlg+instDlg; //同理上面
      acc.SetDelegate(currDlg);
      acc.Withdraw(125);
    }
}
  

这是个简单的例子来说明如何使用delegate,过几天我会更加深入的来说明delegate的。
 

posted on 2006-01-21 20:57  飞狼博客  阅读(2194)  评论(1)    收藏  举报