C#委託

C# 委託類似於C語言或C++中函數的指針。委託是一個引用類型變量,它保存對方法的引用。 引用可以在運行時更改。

委託一般用於實現事件和回調方法。所有委託都隱式地從System.Delegate類派生。

聲明委託

委託聲明確定委託可引用的方法。委託可以引用一個方法,它具有與委託相同的簽名。

例如,考慮下面一個委託:

public delegate int MyDelegate (string s);

上述委託可用於引用具有單個字符串參數並返回int類型變量的任何方法。

委託聲明的語法是:

delegate <return type> <delegate-name> <parameter list>

實例化委託

當聲明瞭一個委託類型後,必須要使用new關鍵字創建一個委託對象,並將其與特定的方法相關聯。創建代理時,傳遞給新表達式的參數類似於方法調用,但不包含方法的參數。 例如:

public delegate void printString(string s);
...
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);

以下示例演示了可以用於引用取整數參數並返回整數值的方法委託的聲明,實例化和使用。

using System;

delegate int NumberChanger(int n);
namespace DelegateAppl
{
   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)
      {
         //create delegate instances
         NumberChanger nc1 = new NumberChanger(AddNum);
         NumberChanger nc2 = new NumberChanger(MultNum);

         //calling the methods using the delegate objects
         nc1(25);
         Console.WriteLine("Value of Num: {0}", getNum());
         nc2(5);
         Console.WriteLine("Value of Num: {0}", getNum());
         Console.ReadKey();
      }
   }
}

當上述代碼被編譯並執行時,它產生以下結果:

Value of Num: 35
Value of Num: 175

委託組播

代理對象可以使用「+」運算符來組合。一個委託調用它由兩個委託組成。只能組合相同類型的委託。「-」運算符可用於從組合委託中刪除組件委託。

使用委託的這個屬性,可以創建一個方法的調用列表,該方法將在調用委託時調用。這稱爲委託組播。以下程序演示了一個委託組播:

using System;

delegate int NumberChanger(int n);
namespace DelegateAppl
{
    class TestDelegate
    {
        static int num = 100;
        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)
        {
            //create delegate instances
            NumberChanger nc;
            NumberChanger nc1 = new NumberChanger(AddNum);
            NumberChanger nc2 = new NumberChanger(MultNum);
            nc = nc1;
            nc += nc2;

            //calling multicast
            nc(5);
            Console.WriteLine("Value of Num: {0}", getNum());
            Console.ReadKey();
        }
    }
}

當上述代碼被編譯並執行時,它產生以下結果:

Value of Num: 525

使用委託

以下示例演示了使用委託。委託printString可用於引用方法,該方法將字符串作爲輸入,並且不返回任何內容。

使用這個委託來調用兩個方法,第一個將字符串打印到控制檯,第二個打印到一個文件中:

using System;
using System.IO;

namespace DelegateAppl
{
   class PrintString
   {
      static FileStream fs;
      static StreamWriter sw;

      // delegate declaration
      public delegate void printString(string s);

      // this method prints to the console
      public static void WriteToScreen(string str)
      {
         Console.WriteLine("The String is: {0}", str);
      }

      //this method prints to a file
      public static void WriteToFile(string s)
      {
         fs = new FileStream("c:\\message.txt",
         FileMode.Append, FileAccess.Write);
         sw = new StreamWriter(fs);
         sw.WriteLine(s);
         sw.Flush();
         sw.Close();
         fs.Close();
      }

      // this method takes the delegate as parameter and uses it to
      // call the methods as required
      public static void sendString(printString ps)
      {
         ps("Hello World");
      }
      static void Main(string[] args)
      {
         printString ps1 = new printString(WriteToScreen);
         printString ps2 = new printString(WriteToFile);
         sendString(ps1);
         sendString(ps2);
         Console.ReadKey();
      }
   }
}

當上述代碼被編譯並執行時,它產生以下結果:

The String is: Hello World