天天看點

委托與事件

首先多謝網上的大牛們無私地分享自己的經驗,讓我這樣的小鳥能站在巨人的肩膀上不斷前進!

  以下是我的總結:

委托                                                                    

  msdn把委托描述為面向對象、類型安全、可實作多點傳播的函數指針。

  1、面向對象:.net把委托(函數指針)定義為類型,具體的類名為委托名稱,并且存在繼承關系:自定義委托<--system.multicastdelegate<--system.delegate。

  2、類型安全:委托

對象中有_target、_methodptr、_methodptraux三個變量。當委托執行個體指向某個執行個體方法時,_target指向執行個體對

象,_methodptr指向執行個體方法的jit

stub(如果經過了jit編譯,就直接指向執行個體方法的記憶體位址),_methodptaux為0;當委托執行個體指向某個靜态方法時,_target指向委

托執行個體本身,_methodptr指向stub(一小段代碼,用于讓clr把_target設為null),_methodptaux指向靜态方法的記憶體

位址。從上面可以看出委托執行個體中不僅儲存了函數的位址,還儲存了函數所在類的執行個體,相反看一下c++的函數指針隻是儲存函數的位址,而不管執行個體函數屬于哪

一個類。

  3、可實作多點傳播:通

過+=、—=添加(移除)函數指針。執行個體化委托時,mydelegate d = new

mydelegate(my)為單點傳播形式;mydelegate d += new mydelegate(my),d += new

mydelegate(my1)為多點傳播形式。添加(移除)函數指針實際調用了multicastdelegate的combineimpl方法把函數指針

添加到_invocationlist(類型為object數組),可以同過委托執行個體.getinvocationlist()方法擷取。

  注意:在多點傳播情況,假如某些函數有傳回值,那麼要使用下列方式來擷取傳回值。

并非像(參考2)裡面說的多點傳播中的函數不能有傳回值。

事件                               

  下面是自己的總結。

  委托對象定義為public後不僅所屬類内部能調用,類外部也能調用;事件不管即使定義為public,也隻能在所屬類的内部觸發,而類外部隻能訂閱不能觸發事件。

總結                             

  使用事件可以降低耦合度,事件的觸發與事件的訂閱分離,讓感興趣的對象訂閱某個對象的全部或部分事件。