c#基礎(chǔ)——事件

引文:http://www.cnblogs.com/OpenCoder/archive/2009/09/23/1572646.html

c#事件

了解委托之后,就可以來談?wù)勈录?,C#事件是什么?

c#事件的定義和委托的聲明是如此的相似:

event <委托類型> 事件名

例子:public event CheckDelegate checkEvent;

上面的例子聲明了個事件叫checkEvent你會發(fā)現(xiàn)它只比聲明委托實(shí)例前多了個關(guān)鍵字event

聲明了事件后就可以實(shí)例化事件,注冊函數(shù)到事件,解除事件函數(shù)注冊其方法和委托的步驟如出一轍:

例子:checkEvent+=new CheckDelegate(CheckMod);//將函數(shù)CheckMod注冊到事件checkEvent上

checkEvent+=CheckMod;//.net 2.0開始支持這種方法

checkEvent-=newCheckDelegate(CheckMod);//將函數(shù)CheckMod解除對事件checkEvent的注冊

checkEvent-=CheckMod;//.net 2.0開始支持這種方法

從種種跡象都可以看出事件和委托實(shí)例是那么的相似,那么為什么不直接用委托還要用到事件呢?其實(shí)事件就是對委托的封裝,就如同c#類中屬性對字段的封裝一樣,其封裝后可以在委托上封裝更復(fù)雜的邏輯,下面我們來看c#中事件的兩種聲明方式,來了解事件對委托的封裝

隱式聲明事件

這種方式聲明事件很簡單,就如同聲明委托實(shí)例一樣:

event <委托類型> 事件名;

例子:public event CheckDelegate checkEvent;

我們用反射機(jī)制來看看這樣聲明的事件里面裝的到底是什么東西

我們可以看到在事件被編譯后自動生成了個private的委托實(shí)例checkEvent和兩個函數(shù)add_checkEvent和remove_checkEvent,這兩個函數(shù)分別對應(yīng)事件的+=/-=操作,另外可以看到在聲明了事件后的確是產(chǎn)生了一個和事件同名私有的委托實(shí)例checkEvent,對事件的+=/-=操作都會反映在這個同名委托實(shí)例checkEvent上,所以可以在定義事件的類里面直接調(diào)用checkEvent()來執(zhí)行注冊函數(shù)和對checkEvent使用=號重新賦值,實(shí)際上這里操作的并不是checkEvent事件,而操作的是同名委托實(shí)例checkEvent,因此隱式聲明的事件,其實(shí)就是由一個委托實(shí)例和兩個函數(shù)封裝而成,所有的操作最終都反映在委托實(shí)例上。

(這里我補(bǔ)充下我的個人理解:事實(shí)上在一個類的內(nèi)部是無法定義一個事件后又定義一個和事件同名的委托實(shí)例的,如果你在本例中嘗試再定義CheckDelegate checkEvent,編譯的時(shí)候會報(bào)錯并提示已經(jīng)定義了名叫checkEvent的委托,原因是因?yàn)槭录緛砭褪且环N特殊的委托實(shí)例(不管是隱式或顯式聲明的事件都是這樣),因此定義和事件同名的委托實(shí)例會報(bào)錯,所以我個人認(rèn)為.net在編譯的時(shí)候會把隱式聲明的事件編譯成為委托實(shí)例(和事件同名),本例中的checkEvent事件在編譯后也不再是事件轉(zhuǎn)而被編譯成了checkEvent委托實(shí)例,否則又怎么可能在定義事件的類的內(nèi)部可以執(zhí)行事件和對事件賦值呢(這里大家可以看看我給的顯式聲明事件的例子,那里面有說到),唯一的解釋就是隱式聲明的事件其實(shí)就是委托實(shí)例)顯式聲明事件

其實(shí)顯示聲明事件就是要自己來手動實(shí)現(xiàn)隱式聲明事件的一個委托實(shí)例

和兩個函數(shù):

event <委托類型> 事件名

{

add

{

//將函數(shù)注冊到自己定義的委托實(shí)例

}

remove

{

//解除函數(shù)對自己定義的委托實(shí)例的注冊

}

}

例子:private CheckDelegate _checkDelete;

public event CheckDelegate checkEvent

{

add

{

_checkDelete = Delegate.Combine(_checkDelete, value) as CheckDelegate;

}

remove

{

_checkDelete = Delegate.Remove(_checkDelete, value) as CheckDelegate;

}


//Delegate.Combine和Delegate.Remove是.net庫函數(shù),作用是合并委托實(shí)例注冊函數(shù)和移除委托實(shí)例注冊函數(shù)并返回合并和移除后的委托實(shí)例,具體解釋請查閱MSDN

我們再用反射機(jī)制查看顯式聲明事件編譯后的代碼

可以看到顯示聲明事件的代碼編譯后和隱式聲明事件的代碼幾乎相同,只不過這里我們自己定義了事件操作委托實(shí)例_checkDelete。另外顯式聲明的事件不支持直接調(diào)用,就算在定義事件的類里面也不能直接調(diào)用顯式聲明的事件(checkEvent();//這樣會報(bào)錯),應(yīng)該調(diào)用事件委托實(shí)例(_checkDelete();)。


參考博客:http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx


簡書代碼的閱讀性還是很差的。不適合寫有含有代碼的文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容