關(guān)于C#中的委托與事件以及兩者之間的關(guān)系

? 一 ?關(guān)于委托

1.委托的概念:

? ? C# 中的委托(Delegate)是一種引用類型變量,它類似于C的函數(shù)指針,可以將方法當(dāng)做參數(shù)的形式進(jìn)行調(diào)用,將一個方法以變量的形式保存起來.我們一般在C#中使用委托來進(jìn)行一種方法的傳遞或者回調(diào).在Xamarin.iOS中為了解決代理中事件的傳遞,我們就可以通過C#的委托進(jìn)行實現(xiàn).

2.委托的聲明:

? ? 委托的聲明格式非常簡單.

?? ? public|權(quán)限,可省略 delegate|委托關(guān)鍵字 return type|委托方法的返回值 name|委托名 (type1 name1,type2 name2,...)|委托方法的參數(shù)列表;

? ? ?例1:我要聲明一個能攜帶返回值為void,無參方法的委托 delegate void MyDelegate ();

? ? ?例2:我要聲明一個公開的能攜帶返回值為int,有兩個int參數(shù)方法的委托: public delegate int MyDelegate(int num1,int num2);

3,委托的實例化:

? ? ? 委托的實例化必須使用new關(guān)鍵字,并同時提供一個特定的方法,該方法的類型必須和你聲明的委托一致,例如我要實例化以上聲明例子2中的委托.

? ? public int sum(int num1,int num2){

? ? ? ? return num1+num2;

? ?}

? ? ?MyDelegate del = new MyDelegate(sum);?

4.委托使用的示例:

? ? ? 這里給大家提供w3cschool中對于委托的示例

附上w3cschool對于委托介紹的原地址以表感謝:www.w3cschool.cn/csharp/csharp-delegate.html

? 二? 關(guān)于事件

寫在前面:

? ? ?C#中關(guān)于事件的介紹有很多,并且關(guān)于事件存在的必要性,似乎設(shè)計者本身沒有太多的考慮,至少我覺得事件能做到的事情,似乎委托也能做到,所以筆者一直很困惑,于是我查找了各種資料,但我個人覺得上面寫的都不夠直白難以理解,也或許是我才接觸的原因,所以理解上有些困難,在我看了不下一周的各類資料后,覺得有必要寫一篇自己的見解,希望能對同樣才接觸C#的新手有所幫助.

1.事件的概念:

? ? ?事件(Event)基本上說是一個用戶操作区岗,如按鍵身腻、點擊、鼠標(biāo)移動等等泉粉,或者是一些出現(xiàn)挠蛉,如系統(tǒng)生成的通知。應(yīng)用程序需要在事件發(fā)生時響應(yīng)事件。例如,中斷袖牙。事件是用于進(jìn)程間通信。

? ? ?以上是w3cschool中對事件的說明.讓我們再來看看官方對事件的介紹:

? ? ?類或?qū)ο罂梢酝ㄟ^事件向其他類或?qū)ο笸ㄖl(fā)生的相關(guān)事情舅锄。 發(fā)送(或引發(fā))事件的類稱為“發(fā)行者”鞭达,接收(或處理)事件的類稱為“訂戶”。

? ? ?在典型的 C# Windows 窗體或 Web 應(yīng)用程序中皇忿,可訂閱由按鈕和列表框等控件引發(fā)的事件畴蹭。 可以使用 Visual C# 集成的開發(fā)環(huán)境 (IDE) 來瀏覽控件發(fā)布的事件,并選擇想要處理的事件鳍烁。 IDE 將自動添加空白事件處理程序方法和訂閱該事件的代碼叨襟。 有關(guān)詳細(xì)信息,請參閱如何:訂閱和取消訂閱事件老翘。

說了這么多巴拉巴拉一大堆的東西,我無非就總結(jié)出了這幾點:

1.事件可以用在類與類之間消息傳遞.

2.發(fā)送事件的類是發(fā)送者,接收事件的類可以作為接受者,一個事件必須要這兩個類.

3.事件可以用來進(jìn)程之間通信

? ? ?其實然并卵,這些東西委托不就能做嗎?我要這事件何用?先別著急,咱們一步步來!

2.事件的聲明:

? ? ?事件的聲明有兩種方式,需要依托于委托的聲明:

? ? 1.隱式聲明事件

? ? ?這種方式聲明事件很簡單芹啥,就如同聲明委托實例一樣:

? ? ?public|權(quán)限(可省略) event|關(guān)鍵字 Delegate|委托類型 name|事件名;

? ? ?例如:

? ? ?public void MyDelegate();

? ? ?public event MyDelegate evt;

? ? ?2.顯式聲明事件

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

和兩個函數(shù):

? ? ?例:

? ? ? ? ?public void MyDelegate();

? ? ? ? ?public MyDelegate _del;

? ? ? ? ?public event <委托類型|MyDelegate> evt

? ? ?{

? ? ? ? ? ? ? ? ?add

? ? ? ? ? ? ?{

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

? ? ? ? ? ? ? ? _del = Delegate.Combine(_del, value) as MyDelegate;

? ? ? ? ? ? ?}

? ? ? ? ? ? ? ?remove

? ? ? ? ? ? {

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

? ? ? ? ? ? ? ? ? _del = Delegate.Remove(_del, value) as MyDelegate;

? ? ? ? ? ? ?}

? ? ? }

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

3.事件的實例化:

? ? ?關(guān)于事件的實例化比較簡單,其實和委托基本是一樣的.

? ? ?例如:我要將上述例子中的事件實例化.

? ? ?public void test(){ ??

? ? ? ? ?Console.WriteLine("test");

? ? ?}

? ? ?evt = new MyDelegate(test);

? ? ?在.Net 2.0后可以通過簡寫的方法來實例化一個事件.

? ? ?evt = test;

? ? ?當(dāng)然,你也可以通過添加訂閱和刪除訂閱來為事件賦值.

? ? ?evt += new MyDelegate(test);

? ? ?evt -= new MyDelegate(test);

? ? ?添加訂閱以及刪除訂閱實質(zhì)上就是調(diào)用了add方法和remove方法,當(dāng)然.Net 2.0后也支持簡寫方式.

? ? ?evt += test; evt -= test;

? ? ?附w3cschool對事件的講解:www.w3cschool.cn/csharp/csharp-event.html

4.解決之前的疑惑:

? ? ? 看了上述的介紹可以發(fā)現(xiàn)事件和委托實例是那么的相似,那么為什么不直接用委托還要用到事件呢汽纠?在解答之前我希望讀者能先看一下我寫的demo案例.

? ? ? 應(yīng)用實例:

圖1
圖2
圖3

? ? ? 該案例使用了純委托和事件兩種方式實現(xiàn)監(jiān)聽value值的變化,細(xì)心的讀者可以發(fā)現(xiàn),我在使用純委托時候在Test類外聲明了委托類型,Test類里聲明了持有委托實例,為什么要兩次聲明?這就是關(guān)鍵點.測試發(fā)現(xiàn)在C#類里是無法通過委托類型去創(chuàng)建它的實例對象的,那么問題來了,如果不實例化,當(dāng)我在一個類里如何發(fā)送消息給我的委托對象呢?所以我只能提前聲明了委托對象后,再聲明我持有該委托類型的對象,通過該對象去調(diào)用委托對象的方法!

? ? ? 回到事件的聲明這塊,我們回顧一下事件的顯式聲明:

? ? ? public void MyDelegate();

? ? ? public MyDelegate _del;

? ? ? public event <委托類型|MyDelegate> evt ? ?

? ? ?{

? ? ? ? ? ? ? ?add

? ? ? ? ?{

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

? ? ? ? ? ? ? _del = Delegate.Combine(_del, value) as MyDelegate;

? ? ? ? }

? ? ? ? ? ? ?remove

? ? ? ?{

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

? ? ? ? ? ? ?_del = Delegate.Remove(_del, value) as MyDelegate;

? ? ? ? }

? ? }?

? ? 我們可以發(fā)現(xiàn)事件的顯式聲明其實給我們做了幾件事:1.定義一個和事件同名的委托實例,2.手動實現(xiàn)add(訂閱)和remove(刪除訂閱)的方法.以便于事件更為便攜的添加和刪除一些委托中的操作.

? ? 也正是因此,在我上面的案例中,當(dāng)我在類里聲明了委托對應(yīng)類型的事件后,不必去聲明持有委托對應(yīng)的實例,而是直接可以調(diào)用事件的操作,也能夠去為其添加和刪除訂閱!

? ? 這也就是為什么我們說事件是對委托進(jìn)行的高度封裝(笑~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卫键,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子虱朵,更是在濱河造成了極大的恐慌莉炉,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碴犬,死亡現(xiàn)場離奇詭異絮宁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)服协,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門绍昂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人偿荷,你說我怎么就攤上這事。” “怎么了盯仪?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵绝骚,是天一觀的道長。 經(jīng)常有香客問我寺庄,道長艾蓝,這世上最難降的妖魔是什么力崇? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮赢织,結(jié)果婚禮上餐曹,老公的妹妹穿的比我還像新娘。我一直安慰自己敌厘,他們只是感情好台猴,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著俱两,像睡著了一般饱狂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宪彩,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天休讳,我揣著相機(jī)與錄音,去河邊找鬼尿孔。 笑死俊柔,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的活合。 我是一名探鬼主播雏婶,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼白指!你這毒婦竟也來了留晚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤告嘲,失蹤者是張志新(化名)和其女友劉穎错维,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體橄唬,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡赋焕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了仰楚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隆判。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缸血,靈堂內(nèi)的尸體忽然破棺而出蜜氨,到底是詐尸還是另有隱情,我是刑警寧澤捎泻,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布飒炎,位于F島的核電站,受9級特大地震影響笆豁,放射性物質(zhì)發(fā)生泄漏郎汪。R本人自食惡果不足惜赤赊,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望煞赢。 院中可真熱鬧抛计,春花似錦、人聲如沸照筑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凝危。三九已至波俄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛾默,已是汗流浹背懦铺。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留支鸡,地道東北人冬念。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像牧挣,于是被迫代替她去往敵國和親急前。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容