漫谈委托和事件
? ? ? 委托和事件是C#中相當重要的部分,先簡單科普一下這兩個概念的定義:
? ? ? 委托delegate 關鍵字用于聲明一個引用類型,該引用類型可用于封裝命名方法或匿名方法。委托類似于 C++ 中的函數指針;但是,委托是類型安全和可靠的。——msdn
? ? ? 事件event是特殊類型的多路廣播委托,僅可從聲明它們的類或結構(發行者類)中調用。 如果其他類或結構訂閱了該事件,則當發行者類引發該事件時,會調用其事件處
理程序方法。事件可標記為 public、private、protected、internal 或protectedinternal。 這些訪問修飾符定義類的用戶訪問事件的方式。——msdn
? ? ? 估計能真正理解這兩段話的都是大牛,我輩菜鳥只能“噢,原來如此,還是不懂...” 最近菜鳥D在項目中使用到了委托,剛好有大牛路過,就請他幫忙診斷一下。
代碼簡化如下:
1 namespace abc{ 2 3 public delegate void xxxdelegate();//委托的聲明 4 5 class abc 6 { 7 public xxxdelegate xxx; 8 9 public void a() 10 { 11 } 12 13 public void b() 14 { 15 } 16 17 public void c() 18 { 19 } 20 21 public void main() 22 { 23 ... 24 pd(); 25 xx(); 26 } 27 28 public void pd() 29 { 30 if () 31 { 32 xxx = a; 33 } 34 else if () 35 { 36 xxx = b; 37 } 38 else 39 { 40 xxx = c; 41 } 42 } 43 44 public void xx() 45 { 46 ... 47 xxx(); 48 } 49 } 50 }? ? ? 大牛看完代碼,皺了皺眉頭,“委托不是這么用的啊...”
? ? ? “委托不是一個安全的函數指針,可以把方法當成變量來使用的么?”菜鳥D不解。
? ? ? “這么理解委托是不錯的,但是它的應用場景不對啊,這些都是自己的方法,為什么不用一個判斷,把判斷的邏輯封裝成方法,直接調用方法呢?這樣看,你的委托是不是沒有什么用?”大牛很耐心,“委托,委托,顧名思義應該執行的是別人的方法呀?。”
? ? ?菜鳥D無話可說了,因為這么寫只是在用“指針”的思想,而委托的本意卻是被拋在了一邊,“那么,委托的應用場景應該是什么?”。
? ? “委托通常在處理異步線程時才會使用,而且它也是事件的基礎。委托定義一種類型,事件可以看做這種類型的一個變量,你在反編譯時也肯定見過,事件會被反編譯成一個私有的委托以及 +=和-= 兩個共有的方法供外部來使用。所以它的使用場景就很明顯了,使用事件的時候,異步線程調用的時候。我建議你看看設計模式中的訂閱發布模式。”
? ? ?菜鳥D找了一下資料,發現各種資料說的亂七八糟,就在這時大牛給了一個很簡單的例子,他指著電腦的USB口,“我不知道這里會插入什么設備,但是我定義了一個規格,只要符合這個規格,就可插進來。事件也是這樣,假設是一個button,我不知道點擊它會有什么效果,我就給它(button)封裝一個點擊事件,你只需要在外部注冊這個事件,就可以讓它在點擊時有你想要的效果。spring的依賴注入也是這么回事,那個經常通過接口來注入,這個則是通過事件這個‘接口’或者叫‘插口’來實現,事件的內部又是委托,其實就是這么個關系。”
? ? ?菜鳥D仔細想了想,結合原來的經驗——在模態對話框或者主窗體和子窗體(并非是繼承關系的父子窗體,而是由主窗體創建的)之間通信時會出現委托,至于上面代碼的“指
針”確實是個笑話。
? ? 總結:委托的使用場景:異步進程和事件的使用。
? ? ? ? ? ? 訂閱者模式:如果不太懂,可以參閱:http://blog.csdn.net/tjvictor/article/details/5223309
? ? ? ? ? ? spring的依賴注入思想到下一篇再寫,不好意思了。
? ? 菜鳥D希望這篇漫談對您有所幫助。
轉載于:https://www.cnblogs.com/cnDqf/p/4077136.html
總結
- 上一篇: checkbox全选衍生问题讨论
- 下一篇: C#导出Excel和相关打印设置