表面上看來(lái)使用delegate是一件很簡(jiǎn)單的事。
用delegate關(guān)鍵字定義,使用老套的new創(chuàng)建一個(gè)instance ,使用熟悉的方法調(diào)用寫法調(diào)用,只不過不在是方法名,而是委托名。但是在這背后CLR為我們做了很多。當(dāng)我們 寫下下面這句話時(shí)public delegate void FeedBack(Int32 val);其實(shí)相當(dāng)于 大概下面的代碼(省略部分多線程相關(guān)代碼)pubic class FeedBack:MulticastDelegate{ public FeedBack(Object object , IntPtr methodPtr) { xxxx } public virtual void Invoke(int32 val);}首先delegate 就是一個(gè)class。這個(gè)class會(huì)自動(dòng)繼承MuticastDelegate .然后,這個(gè)class 的構(gòu)造函數(shù)就如上面所示,我們先看第二個(gè)參數(shù) methodPtr 可以理解為函數(shù)的指針,或者說(shuō)函數(shù)的地址。委托在真正運(yùn)行的時(shí)候,就要找到這個(gè)函數(shù)的地址,并運(yùn)行這個(gè)函數(shù)。對(duì),我們要先找到這個(gè)函數(shù)的地址,對(duì)于 static類型的函數(shù),地址是確定的,而對(duì)于實(shí)例函數(shù)而言,內(nèi)部的函數(shù)地址則是不定的,它需要先確定具體的某個(gè)實(shí)例, 這既是第一個(gè)參數(shù)的用途,具體實(shí)例的引用,對(duì)于static類型的函數(shù),就會(huì)默認(rèn)傳入一個(gè)null。其實(shí),在基類 MutiCastDelegate中,有三個(gè)重要的非公開屬性_target_methodPtr_invokationlist一二兩個(gè)屬性 剛好對(duì)應(yīng)我們構(gòu)造函數(shù)傳入的兩個(gè)參數(shù),第三個(gè)屬性和委托鏈有關(guān),默認(rèn)為null,我們先不討論。也就是說(shuō):delegate 其實(shí)只是個(gè)wrapper ,包裝著需要真正操作的對(duì)象 以及它的方法。.png)
也就是說(shuō)委托的構(gòu)造函數(shù) 完成了 和具體真實(shí)對(duì)象以及真實(shí)方法的對(duì)應(yīng),而調(diào)用則是另一個(gè)方法 Invoke(int32 val)。這個(gè)方法會(huì)觸發(fā)真實(shí)方法的調(diào)用。 public delegate void FeedBack <T>(T para); public delegate void FeedBack<Tint,Tstr>(Tint para1,Tstr para2); class 委托可以有泛型嗎 { public static void Main(string[] args) { FeedBack<Int32 > fb = new FeedBack<int >(FeedBackInt); FeedBack<String > fb2 = new FeedBack<string >(FeedbackString); FeedBack<int ,string > fb3 = new FeedBack<int , string >(FeedbackIntString); fb.Invoke(2); fb2.Invoke( "haha"); fb3.Invoke(60,"haha" ); Console.ReadKey(); } public static void FeedBackInt(Int32 val) { Console.WriteLine(val); } public static void FeedbackString(String str) { Console.WriteLine(str); } public static void FeedbackIntString(int val,string str) { Console.WriteLine(val+":" +str); } }}
不知道看到這里,你心里會(huì)不會(huì)隱隱約約有一種想法。。。。那就是微軟所想到的:通過泛型可以把你編程幾乎會(huì)用到的所有可能的委托囊括?。。。∷麄兇_實(shí)這樣做了。。這就是FCL 擁有的自建委托。不帶返回值的統(tǒng)稱 Action 帶返回值的統(tǒng)稱 Func. 自帶委托如下,參數(shù)最多上限16個(gè)。再多的話,這個(gè)方法本身就很有問題了。
以及
微軟建議,在需要使用委托的時(shí)候就是用內(nèi)建的這些委托,而不要再去自己創(chuàng)建委托類型了。那我們就遵守這個(gè)慣例吧。當(dāng)然 也有可能這些泛型不符合你需要的委托。 比如你需要這個(gè)delegate void bar(ref int32 z); ,或者說(shuō)你的泛型委托需要一些約束。那就得自己定義委托了。。
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注