再探委託與事件

2021-09-22 06:45:12 字數 1994 閱讀 4693

委託

在這裡補充兩個對委託運用得比較少的示例:

一、將委託作為

引數傳遞,然後再呼叫;

二、使用委託呼叫

內部類中的方法;

示例一:委託作為引數

using

system;

using

system.collections.generic;

using

system.text;

namespace

委託作為引數}//

加法public

intadd(

inta, 

intb)

//減法

public

intreduce(

inta, 

intb)

}class

run}}

示例二:委託呼叫內部類的方法

using

system;

using

system.collections.generic;

using

system.text;

namespace

委託呼叫內部類的方法

//內部類的呼叫

public

class

innerclass}}

class

program}}

事件

由於msdn含混不清的誤導,很多人會認為:事件就是一種受限的委託。但實際上不是!

事件與委託

的關係好比

欄位與屬性

的關係。

事件實際上是一種委託屬性,只不過這個屬性過載的不是賦值運算子,而是+=和-=運算子。

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

例如:obj.a 這個屬性

obj.a = "aaa";       將呼叫 set 訪問器:   set

string a = obj.a;   將呼叫 get 訪問器:   get

而事件也是一樣,假設有乙個事件obj.e,則下面的表示式也等同於後面的形式:

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

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

事件與屬性的共同點:

事件也可以被繼承;

事件也可以被重寫;

事件也可以是虛的或者抽象的(表現在add和remove方法是抽象的或者虛的);

理論上,事件的add和remove方法也可以有不同的訪問許可權。

事件與屬性的不同點:

屬性是必須實現的,事件則不必(或者說,事件是最早出現的自動屬性);

與自動屬性一樣,事件也會建立乙個欄位來儲存對應的委託例項,而這個欄位與事件同名且是私有。在c#中,你可以訪問到這個字段,因為它真的就是乙個字段。

換言之,在c#中寫**時,如果是在類的內部使用事件,其實就是引用那個自動生成的私有字段(委託字段)。

而在類的外部使用事件,是不同於在類的內部使用事件(因為這個欄位是私有的,所以在類的外部也就訪問不到)。

event 本質上所做的工作應該還是通過 delegate 來實現的,或者至少原理相同。event 關鍵字只不過是讓clr給所定義的 delegate 物件進行乙個封裝。

event 是通過對 delegate 的限制來封裝一部分本來就不應該暴露在外的行為,從而更符合物件導向的思想(封裝的原則)。

附加:

1、事件其實是由三個方法add、remove和raise組成的。但c#編譯器總是不會生成raise方法。

2、自動事件不同的編譯器實現是不同的,例如vb的編譯器生成的私有欄位是(事件名)event。

3、web開發中的control也是事件驅動的。

委託和事件再探索

一直以為張子陽是位功力深厚的長者,今天才知道他比 我大一歲!功力深厚也就罷了,還長得那麼帥!汗顏!張老師 在技術上不分輩分 的文章我一直關注,由淺及深,能跟著學不少東西非常棒!我看技術從來不做筆記的,以為自己腦子好使,最近 發現老是忘事,看來到了該做筆記的年齡了!具體的關於c 中的委託和事件我就不再...

c 委託和事件再理解

委託 c 中的委託類似於 c 或 c 中的函式指標。使用委託使程式設計師可以將方法引用封裝在委託物件內。然後可以將該委託物件傳遞給可呼叫所引用方法的 而不必在編譯時知道將呼叫哪個方法。與 c 或 c 中的函式指標不同,委託是物件導向 型別安全的,並且是安全的。委託宣告定義一種型別,它用一組特定的引數...

委託與事件

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