转自:http://www.hubwiz.com/


Delegate

  C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。委托特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。

声明委托

  声明委托的语法如下:

    delegate return-type delegate-name (parameter-list);


  其中:return-type是返回类型,delegate-name是委托名字,parameter-list是参数列表。


    public delegate int MyDelegate (string s); //声明一个全局的委托,参数为string类型


方法名作为参数


  委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-else(switch)语句,同时使得程序具有更好的可扩展性。


using System;

using System.Collections.Generic;

using System.Text;

 

namespace Delegate

{

   //定义委托,它定义了可以代表的方法的类型

   public delegate void GreetingDelegate(string name);

   class Program

   {

       private static void EnglishGreeting(string name)

       {

           Console.WriteLine("Morning, " + name);

       }

 

       private static void ChineseGreeting(string name)

       {

           Console.WriteLine("Zao Shang Hao, " + name);

       }

 

       //注意此方法,它接受一个GreetingDelegate类型的方法作为参数

       private static void GreetPeople(string name, GreetingDelegate MakeGreeting)

       {

           MakeGreeting(name);

       }

 

       static void Main(string[] args)

       {

           GreetPeople("Jimmy Zhang", EnglishGreeting); //方法名作为参数传递

           GreetPeople("Zhang Ming", ChineseGreeting);

       }

   }

}



实例化委托


  一旦声明了委托类型,委托对象必须使用 new 关键字来创建,且与一个特定的方法有关。当创建委托时,传递到 new 语句的参数就像方法调用一样书写,但是不带有参数。例如:


    public delegate void printString(string s);

    //...

    printString ps1 = new printString(WriteToScreen);//实例化委托WriteToScreen方法

    printString ps2 = new printString(WriteToFile);


    实例如下:


using System;

namespace DelegateApp

{

   delegate int NumberChanger(int n);

   class TestDelegate

   {

       static int num = 10;

       public static int AddNum(int p)

       {

           num += p;

           return num;

       }

       public static int MultNum(int q)

       {

           num *= q;

           return num;

       }

       public static int getNum()

       {

           return num;

       }

       static void Main(string[] args)

       {

           // 创建委托实例

           NumberChanger nc1 = new NumberChanger(AddNum);

           NumberChanger nc2 = new NumberChanger(MultNum);

           // 使用委托对象调用方法

           nc1(25);

           Console.WriteLine("Value of Num: {0}", getNum());// 35

           nc2(5);

           Console.WriteLine("Value of Num: {0}", getNum()); //175

       }

   }

}


将方法绑定到委托

  可以将多个方法赋给同一个委托,或者叫将多个方法绑定到同一个委托,当调用这个委托的时候,将依次调用其所绑定的方法。委托对象可使用 "+=" 运算符进行合并。只有相同类型的委托可被合并。"-=" 运算符可用于从合并的委托中移除组件委托。


using System;

namespace DelegateAppl

{

  delegate int NumberChanger(int n);

  class TestDelegate

  {

     static int num = 10;

     public static int AddNum(int p)

     {

        num += p;

        return num;

     }

 

     public static int MultNum(int q)

     {

        num *= q;

        return num;

     }

     public static int getNum()

     {

        return num;

     }

 

     static void Main(string[] args)

     {

        // 创建委托实例

        NumberChanger nc;

        NumberChanger nc1 = new NumberChanger(AddNum);

        NumberChanger nc2 = new NumberChanger(MultNum);

        nc = nc1;

        nc += nc2; //合并委托

        nc(5);

        Console.WriteLine("Value of Num: {0}", getNum()); //75

        nc -=nc1;

        nc(5);

        Console.WriteLine("Value of Num: {0}", getNum()); //375

     }

  }

}