? 一 ?關(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)用實例:
? ? ? 該案例使用了純委托和事件兩種方式實現(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;
? ? ? ? }
? ? }?