事件與委託

2021-09-05 21:39:21 字數 1371 閱讀 7324

關於事件與委託,說來慚愧一直沒能對事件進行深入的研究,一直以來有人問我事件到底是什麼。一般都會從用途上加以說明,未曾研究過其實現機制。最近又看到老趙和腦袋兩位對事件的應用擴充套件,下決心徹底把事件的實現研究了一把。

由於msdn

含混不清的誤導,很多人(包括我以前)認為,其實事件就是一種受限的委託。但實際上不是,事件與委託的關係好比欄位與屬性的關係。事件實際上是一種委託屬性,只不過這個屬性過載的不是賦值運算子,而是+=和

-=運算子。

我們知道,對於乙個屬性而言,對他的賦值和取值運算會被轉換為兩個方法的呼叫。

例如obj.a

這個屬性,則下面的表示式等同於後面的形式:

obj.a = 「aaa」;           obj.set_a( 「aaa」 );

string a = obj.a;        string a = obj.get_a();

而事件也是一樣,假設有乙個事件

obj.e

,則下面的表示式也等同於後面的形式:

obj.e += d;              obj.add_e( d )

obj.e -= d;              obj.remove_e( d )

與屬性一樣,事件也可以被繼承甚至重寫。事件也可以是虛的和抽象的,理論上事件的

add和

remove

也可以是有不同的可見性的。

與屬性一樣,抽象和虛的事件,其實就是表現為事件的兩個方法

add和

remove

是抽象的和虛的。

但是!事件與屬性有乙個最明顯的不同,也就是屬性是必須實現的,事件則是不必的。或者說,事件是最早出現的自動屬性。

與自動屬性一樣,事件也會建立乙個欄位來儲存對應的委託例項,而這個欄位與事件同名且是私有。在

c#中,你可以訪問到這個字段,因為它真的就是乙個字段。

換言之,當你在

c#中寫**時,如果是在型別內部使用型別的事件,其實就是引用到那個自動生成的私有字段。換言之,在類的內部使用事件的時候,你使用的是乙個委託欄位而不是事件。對這個欄位的操作是完全不同於在類的外部使用事件的。

當然,一旦事件寫了

add和

remove

訪問器,也就不會被自動實現,也就沒有這個私有欄位了。同樣的,因為這個欄位是私有的,所以,在類的外部也是訪問不到的。

1、事件其實是由三個方法

add、

remove

和raise

組成的。但

c#編譯器總是不會生成

raise

方法。

2、自動事件不同的編譯器實現是不同的,例如

vb的編譯器生成的私有欄位是

(事件名

)event

委託與事件

1.建立乙個類,分別建立加 減 乘 除四個方法,通過委託和事件,實現 輸入兩個計算數,完成所有的四個方法的呼叫,計算出結果顯示。建立乙個警察 policeman 類,乙個小偷 thief 類,例項化兩個類的物件,當policeman類中警笛鳴響 alarm 方法執行時,觸發小偷逃跑 runaway ...

委託與事件

委託就是以方法做引數進行傳遞,它定義的是方法的框架,如果用這個委託,所宣告的方法就必須按照給定的引數及返滬型別進行處理。宣告委託的方式 delegate 返回值型別 委託型別名 引數 比如delegate void stringprocess string s 注意這裡的除了前面的delegate,...

委託與事件

委託與事件 一 委託 delegate 1 委託是一種可以把引用儲存為函式的型別。2 在定義了委託後,就可以宣告該委託型別的變數,接著把這個變數初始化為與委託有相同返回型別和引數類別的函式引用,之後,就可以使用委託變數呼叫這個函式,就像該變數是乙個函式一樣。如 double multiply dou...