深入解析委托
?
先來到一個場景,小明、歐陽轟、王麻子是一個寢室的,有一天小明去吃午飯,歐陽轟說:幫我帶一瓶飲料唄。這里,可以看出一個小小的委托關系,小明是歐陽轟的被委托人(經紀人),歐陽轟不用自己去做,請一個人代替他去做。這個時候王麻子也不想下樓了說:隨便幫我帶一個飯,還來一瓶飲料吧,我不挑食。這里的被委托人可以接受不同的委托人委托的事情,也可以是多件不同的事情。
下面我們用代碼實現,這里呢用兩種方式調用委托:
class Program{//定義委托public delegate void DelegateBring(string name);static void Main(string[] args){Ming ming = new Ming();//聲明委托DelegateBring delegateBring;//實例化委托delegateBring = new DelegateBring(ming.BringDrink);//作為參數傳入方法DelegateReceive(delegateBring, "歐陽轟", "可樂");delegateBring += new DelegateBring(ming.BringFood);delegateBring("王麻子");Console.Read();}public static void DelegateReceive(DelegateBring delegateBring, string stuName, string Drink){//使用傳入方法delegateBring(stuName);Console.WriteLine(" 備注:{0}", Drink);}}class Ming{public void BringFood(string name){Console.WriteLine("幫{0}帶飯", name);}public void BringDrink(string name){Console.WriteLine("幫{0}帶一瓶飲料", name);}}?
輸出:
幫歐陽轟帶一瓶飲料備注:可樂 幫王麻子帶一瓶飲料 幫王麻子帶飯?
這里,我們從剛剛的示例和代碼中分析得出以下結論:
1.我們把相同的操作封裝起來,重復使用,這很符合面向對象編程的思想,減少重復代碼量
?
?
2.通過委托,我們把方法當作參數傳入使用者,這里的小明做的事情可以看作相對的“接口”,這樣的設計符合一個面向對象的原則:面對接口編程,不對實現編程
3.我們可以通過委托訂閱很多個方法,不需要一個一個的去調用,那么實現這個重要功能的就是委托鏈(下面解釋),這個也是委托的一個重要的特色
?
?
接下來我們了解委托的構造
通過斷點我們可以看到我們實例化的delegate是繼承System.MulticastDelegate,點開+號看到有個base,這個就是他的繼承父類,也就是System.Delegate。
?
?
System.Delegate里面有兩個很重要的方法:
1.Combine 添加指定的委托,也就是委托訂閱常用在多播委托,可以用+=來完成
?
?
2.Remove這個方法跟combine方法相對,是取消某個多播委托上面的委托,通常讓委托鏈上指定的委托為null回收內存,可以用-=來完成
System.MulticastDelegate里面的一個方法和兩個屬性,我們通過調試的監視窗口來觀察他們
?
?
Method指向將要調用的方法的地址
?
?
Target這個存儲的是指明調用方法所在的實例對象,如果委托調用的是一個靜態方法,那么這個字段就是一個null,如果調用的是一個實例方法,那么它就是這個方法的對象
GetInvocationList()這個方法是獲取多播委托的數組
?
?
接下來通過斷點查看這兩個類里面的構造
這里我們可以看到關鍵的幾個屬性方法
?
?
_target:對應的是Target屬性
_methodPtr:對應的是Method屬性,這里顯示的是一串數字,可以理解是這個方法的一個回調指針
?
?
_invocationList:對應的是GetInvocationList()委托鏈
那么我們這里在最后面加入一段遍歷這個委托鏈的代碼,然后看看執行委托的順序吧
for (int i = 0; i < delegateBring.GetInvocationList().Count(); i++){Console.WriteLine(delegateBring.GetInvocationList()[i].Method.Name);}?
最后輸出:
BringDrink BringFood?
那么查看了這么多信息,我們根據這些特性畫一畫這個委托鏈吧
總結:從委托的作用,委托的由來,再到一步步的編譯和監控,再到后面的遍歷委托鏈,大家應該對委托有了一個更深的了解。還是那句,習而簡之。希望對大家有幫助
?
寫在最后:這里沒有用到反編譯工具,也沒有貼IL,我感覺這個玩意兒沒多少人能看懂,也不算是匯編語言,所以就用這種斷點,查看監視的方法簡單文雅,準備了一個星期左右,寫著寫著感覺就成了一個靈魂畫家。最后希望大家指出錯誤,給予我建議,愛你們,么么噠
總結
- 上一篇: 如何让搜索引擎抓取AJAX内容
- 下一篇: 简单搞定linux逻辑卷