入行半年多了,委托干什么用的還不知道,真心說不過去了,關鍵對這東西有點恐懼,主要是被老師嚇的,記得我C#專業課老師在講到委托時,原話是這樣的,同學們,委托這個地方是難點,暫時不講,講了你也不懂,等你有了一定的編程經驗,你自會明白。好吧,我懂了,只可意會不可言傳。其實,它并沒有想象中這么恐怖,只不過我被嚇著了,向來就膽小,不敢挑戰有點難度的東西,只能玩玩表面的東西,嗨,不廢話了,但是這是按照博客園慣例來的,一開始不能太專業,專業了就不是“面向對象”了。
好吧,先提個問題,委托到底是什么?這是個頭腦風暴,那家可以隨便想.......是類型?是方法?還是是對象? 大家有沒有說說你的見解的,大多數教程里更愿意把它叫做代理,叫做方法的指針,好吧,又專業了。其實我認為,這幾種的叫法都合適。那它到底是什么?有什么用?為了讓不懂編程的人也能看懂我寫的東西,我舉個實際生活中的例子,比如,二狗,我今天有點事,孩子放學回家沒人做飯,我今天就把他暫時交給你照顧了,好嗎?那這里做飯這件事其實就是C#中的方法,一個事件的處理過程,二狗就是你的委托人,本來你是孩子的監護人,你理應直接照顧孩子的吃飯上學等等,但是今天特殊情況,自己實在做不了,你就把這事暫時委托給你的朋友,讓他幫一下嗎。相信大家懂了嗎,有沒有稍微懂,稍微懂就夠了,我們可以跳到C#里來,重新講述一下委托這個概念,C#中,你本可以直接操作方法,你是方法的創造者(自定義方法),或者,C#為你做好的方法(類庫里的方法),但是我把方法委托給別人來做,但是這個人要有和我一樣的能耐(可以為理解方法簽名要一致)才能幫我完成方法的調用。
補充方法簽名的概念,方法簽名指方法名稱、參數個數、參數類型、方法參數的順序。與方法返回值無關。方法簽名也成為方法標識。
接下來我們按照委托如何定義,如何使用,為什么要使用委托幾個角度學習它。并與C語言中函數指針類比學習。
以實現四則計算器為目的,首先定義加、減、乘、除四個計算方法,在主函數中使用委托的方式進行調用。
class PRogram { delegate int MathDelegate(int i, int j);//delegate 和 Delegate 的區別是什么 static int Add(int i,int j) { return i+j; } static int Subtract(int i,int j) { return i - j; } static int multiply(int i,int j) { return i * j; } static int devide(int i,int j) { return i / j; } static void Main(string[] args) { MathDelegate myDelegate = new MathDelegate(Add); int result=myDelegate(10,20); Console.WriteLine("加法結果是:{0}",result); myDelegate = new MathDelegate(Subtract); result = myDelegate(10, 20); Console.WriteLine("減法結果是:{0}", result); myDelegate = new MathDelegate(multiply); result = myDelegate(10, 20); Console.WriteLine("乘法結果是:{0}", result); myDelegate = new MathDelegate(devide); result = myDelegate(10, 20); Console.WriteLine("除法結果是:{0}", result); Console.ReadKey(); } }
如同i可以接受int類型的“1”,但不能接受bool類型的1一樣。MathDelegata的 參數類型定義 應該能夠確定 MathDelegata可以代表的方法種類,再進一步講,就是MathDelegata可以代表的方法 的 參數類型和返回類型,就是方法簽名的意思。
于是,委托出現了:它定義了MathDelegata參數所能代表的方法的種類,也就是MathDelegata參數的類型。
NOTE:如果上面這句話比較繞口,我把它翻譯成這樣:string 定義了name參數所能代表的值的種類,也就是name參數的類型。
static int Count(int i, int j, MathDelegate myDelegata) { return myDelegata(i,j); }如你所見,委托MathDelegata出現的位置與 int相同,int是一個類型,那么MathDelegata應該也是一個類型,或者叫類(Class)。但是委托的聲明方式和類卻完全不同,這是怎么一回事?實際上,委托在編譯的時候確實會編譯成類。因為Delegate是一個類,所以在任何可以聲明類的地方都可以聲明委托。更多的內容將在下面講述,現在,請看看這個范例的完整代碼:
class Program { delegate int MathDelegate(int i, int j);//delegate 和 Delegate 的區別是什么 static int Add(int i,int j) { return i+j; } static int Subtract(int i,int j) { return i - j; } static int Multiply(int i,int j) { return i * j; } static int Devide(int i,int j) { return i / j; } static int Count(int i, int j, MathDelegate myDelegata) { return myDelegata(i,j); } static void Main(string[] args) { int result = Count(20, 10, Add); Console.WriteLine("加法結果是:{0}",result); result = Count(10, 20,Subtract); Console.WriteLine("減法結果是:{0}", result); result = Count(10, 20,Multiply); Console.WriteLine("乘法結果是:{0}", result); result = Count(10, 20, Devide); Console.WriteLine("除法結果是:{0}", result); Console.ReadKey(); }我們現在對委托做一個總結:
委托是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞,這種將方法動態地賦給參數的做法,可以避免在程序中大量使用If-Else(Switch)語句,同時使得程序具有更好的可擴展性。
說到這里我們已然可以把委托理解為一個類型或一個類,就想String一樣,但是委托有一個特性不同于類型:可以將多個方法賦給同一個委托,或者叫將多個方法綁定到同一個委托,當調用這個委托的時候,將依次調用其所綁定的方法。我們稱它為多播委托,在這個例子中,語法如下:
class Program { delegate int MathDelegate(int i, int j);//delegate 和 Delegate 的區別是什么 static int Add(int i,int j) { Console.WriteLine("加法"); return i+j; } static int Subtract(int i,int j) { Console.WriteLine("減法"); return i - j; } static int Multiply(int i,int j) { Console.WriteLine("乘法"); return i * j; } static int Devide(int i,int j) { Console.WriteLine("除法"); return i / j; } static int Count(int i, int j, MathDelegate myDelegata) { return myDelegata(i,j); } static void Main(string[] args) { //多播委托 MathDelegate myDelegate = new MathDelegate(Add); myDelegate += Subtract; myDelegate += Multiply; myDelegate += Devide; int result = Count(10, 20, myDelegate); Console.WriteLine("結果是:{0}", result); Console.ReadKey(); } }運行結果為

由運行結果分析,當一個委托引用同時指向多個符合方法標識的方法時,此時即構成多播委托。其本質是對System.MulticastDelegate類(為System.Delegate的子類)的繼承和實現。由于一個委托只能有一個返回值,故一般多播委托為void的(并非一定),若有返回值,則最終的返回結果及多播系列中最后一個方法的返回值。
當多播委托的引用只指向一個方法,則其使用方法與單播委托一樣,但是若指向多個方法,則除第一個使用=,其他均用+=。注意這里,第一次用的“=”,是賦值的語法;第二次,用的是“+=”,是綁定的語法。如果第一次就使用“+=”,將出現“使用了未賦值的局部變量”的編譯錯誤。例如:
MathDelegate myDelegate = new MathDelegate(Add); myDelegate += Subtract; myDelegate += Multiply; myDelegate += Devide;
既然一個委托可以綁定方法,就有辦法取消對方法的綁定,很容易想到這個語法:-=
//第三種方式:多播委托 MathDelegate myDelegate = new MathDelegate(Add); myDelegate += Subtract; myDelegate += Multiply; myDelegate += Devide; myDelegate -= Devide;//注意這里的寫法
由上個例子改寫運行結果:

我們看到除法沒有了,是因為解除了對除法的綁定,最后一個方法是乘法,返回的結果是最后一個方法的運算結果。
新聞熱點
疑難解答