關于C#中的委托與事件以及兩者之間的關系

? 一 ?關于委托

1.委托的概念:

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

2.委托的聲明:

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

?? ? public|權限,可省略 delegate|委托關鍵字 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關鍵字,并同時提供一個特定的方法,該方法的類型必須和你聲明的委托一致,例如我要實例化以上聲明例子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

? 二? 關于事件

寫在前面:

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

1.事件的概念:

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

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

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

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

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

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

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

3.事件可以用來進程之間通信

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

2.事件的聲明:

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

? ? 1.隱式聲明事件

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

? ? ?public|權限(可省略) event|關鍵字 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.事件的實例化:

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

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

? ? ?public void test(){ ??

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

? ? ?}

? ? ?evt = new MyDelegate(test);

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

? ? ?evt = test;

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

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

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

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

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

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

4.解決之前的疑惑:

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

? ? ? 應用實例:

圖1
圖2
圖3

? ? ? 該案例使用了純委托和事件兩種方式實現(xiàn)監(jiān)聽value值的變化,細心的讀者可以發(fā)現(xiàn),我在使用純委托時候在Test類外聲明了委托類型,Test類里聲明了持有委托實例,為什么要兩次聲明?這就是關鍵點.測試發(fā)現(xiàn)在C#類里是無法通過委托類型去創(chuà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(刪除訂閱)的方法.以便于事件更為便攜的添加和刪除一些委托中的操作.

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

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

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

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

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