定義:
委託是一種在對象裡儲存方法引用的類型,同時也是一種型別安全的函數指標。
理解委託的一種方式可以把委託的作用當作是給方法簽名指定名稱。
委託的定義類似於方法的定義,但沒有方法體,定義的委託名前要加上關鍵字delegate。
因為定義委託基本上是定義一個新類,所以可以在定義類的任何地方定義委託,既可以在另一個類的內部定義委託,也可以在所有類的外部定義委託,還可以在命名空間中把委託定義為頂層對象。根據定義的可見度,可以在委託定義上添加一般的存取修飾詞:public、private和protected等:
一個委託執行個體壓縮(或者稱為封裝)了一個方法稱之為“一個可調用的實體” ,所以“一個可調用的實體”也就由這個委託執行個體本身和執行個體中封裝的方法組成
委託也可以包含多個方法,這種委託稱為多播委託。
如果調用多播委託,就可以按順序連續調用多個方法。為此,委託的簽名就必須返回 void (否則,傳回值應送到何處?)(當委託只包含一個方法的時候,其傳回型別的聲明可以參照所封裝的方法,不一定必須是void)。實際上,如果編譯器發現某個委託返回 void ,就會自動假定這是一個多播委託。
委託的優點:
(1)壓縮方法的調用。(2)合理有效地使用委託能提升應用程式的效能。(3)用於調用匿名方法。
委託的聲明:範圍修飾符 delegate 委託傳回型別 委託名();
如:public delegate Void Test();注意點:可以在不帶參數或參數列表的情況下聲明委託。應當遵循和聲明方法一樣的文法來聲明委託.
委託的樣本程式:public delegate double Delegate_Prod(int a, int b);
class Class1
{
static double fn_Prodvalues(int val1, int val2)
{
return val1 * val2;
}
static void Main(string[] args)
{
//Creating the Delegate Instance
Delegate_Prod delObj = new Delegate_Prod(fn_Prodvalues);
Console.Write("Please Enter Values");
int v1 = Int32.Parse(Console.ReadLine());
int v2 = Int32.Parse(Console.ReadLine());
//use a delegate for processing
double res = delObj(v1, v2);
Console.WriteLine("Result :" + res);
Console.ReadLine();
}
}
解釋:上面我用一段小程式示範了委託的使用。委託Delegate_Prod聲明時指定了兩個只接受整型變數的傳回型別。同樣類中名為fn_Prodvalues的方法也是如此,委託和方法具有相同的簽名和參數類型。在Main方法中建立一個委託執行個體並用如下方式將函數名稱傳遞給該委託執行個體:Delegate_Prod delObj = new Delegate_Prod(fn_Prodvalues);這樣我們就接受了來自使用者的兩個值並將其傳遞給委託:delObj(v1,v2);在此委派物件壓縮了方法的功能並返回我們在方法中指定的結果。
多播委託:(1)多播委託包含一個以上方法的引用。(2)多播委託包含的方法必須返回void,否則會拋出run-time exception。
多播委託的樣本程式:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp1
{
//聲明一個委託
public delegate void msg();
//編寫一個類
class messges
{
//messges類下的一個成員方法m1
public static void m1()
{ Console.WriteLine("方法一被huashanlin調用"); }
//messges類下的一個成員方法m2
public static void m2()
{ Console.WriteLine("方法二被huashanlin調用"); }
//messges類下的一個成員方法m3
public static void m3()
{ Console.WriteLine("方法3huashanlin被調用"); }
}
//另一個類
class Program
{
//該類下包含的主函數
static void Main(string[] args)
{
//執行個體化一個委託,並封裝messges類中的一個方法m2
msg ms = new msg(messges.m2);
//在原有的封裝了一個m1方法的委託執行個體中再封裝進一個新的方法m1
ms = ms + messges.m1;
//或者上面的語句可以寫成ms += messges.m1;兩者的效果是一樣的
//以下為該委託執行個體封裝第三個方法
ms += messges.m3;
//調用該委託執行個體,那麼由於多播委託之後調用該委託就要執行完此封裝進去的三個方法
ms();
}
}
}
//註:deletge儲存的方法簽名是以hash隊列的形式存在的
多播委託樣本程式二:
delegate void Delegate_Multicast(int x, int y);
Class Class2
{
static void Method1(int x, int y) {
Console.WriteLine("You r in Method 1");
}
static void Method2(int x, int y) {
Console.WriteLine("You r in Method 2");
}
public static void Main()
{
Delegate_Multicast func = new Delegate_Multicast(Method1);
func += new Delegate_Multicast(Method2);
func(1,2); // Method1 and Method2 are called
func -= new Delegate_Multicast(Method1);
func(2,3); // Only Method2 is called
}} 解析:上面的樣本程式分別定義了名為method1 和 method2的兩個接受整型參數、傳回型別為void的方法。在Main函數裡使用下面的聲明建立委派物件:Delegate_Multicast func = new Delegate_Multicast(Method1);然後使用+= 來添加委託,使用-=來移除委託。