淺析C#中的事件

來源:互聯網
上載者:User

標籤:ret   傳遞   應用程式   ati   namespace   div   通過   comm   handler   

講過了委託,不得不講事件。

事件基於委託,為委託提供了一種發布/訂閱機制。

在發生其他類或對象關注的事情時,類或對象可通過事件通知它們。發送(或引發)事件的類稱為“發行者”,接收(或處理)事件的類稱為“訂戶”。

在典型的 C# Windows 表單或 Web 應用程式中,可訂閱由控制項(如按鈕和列表框)引發的事件。可使用 Visual C# 整合式開發環境 (IDE) 來瀏覽控制項發布的事件,選擇要處理的事件。IDE 會自動添加空事件處理常式方法和訂閱事件的代碼。

事件時對委託的封裝。

事件協助解決委託封裝問題。事件位於委託的頂部,並提供封裝,使得目標源只能聽而不能完全控制的委派物件。

顯示了事件的樣子: -

理解事件:

Button是一個類,當你點擊按鈕的時候,Click事件被觸發。

定時器是一個類,每毫秒tick事件被觸發。

下面通過一個例子來講述一下事件的應用。

定義兩個類CarDealer和Consumer。CarDealer類提供了一個新車到達時觸發的事件,Consumer類訂閱該事件,以獲得新車到達的通知。

事件發行者:CarDealer類提供了EventHandler類型的NewCarInfo事件。事件一般使用帶兩個參數的方法。第一個參數是一個對象,包含事件的寄件者;第二個參數提供了事件的相關資訊。

你可能感到吃驚,沒有定義委託怎麼就定義事件了??其實有了泛型委派EventHandler 委託後,就不再需要委託了。

EventHandler 的文法如下:

public delegate void EventHandler(Object sender,TEventArgs e) where TEventArgs : EventArgs

EventHandler定義了一個處理常式,返回void,接受兩個參數。第一個參數必須是object,第二個參數是T類型,對於T有一個約束,就是它必須派生自基類EventArgs。下面代碼的CarInfoEventArgs就派生自基類EventArgs.

EventArgs是包含事件數目據的類的基類,此類不包含事件數目據,在事件引發時不向事件處理常式傳遞狀態資訊的事件會使用此類。如果事件處理常式需要狀態資訊,則應用程式必須從此類派生一個類來儲存資料。事件處理常式委託的標準簽名定義一個沒有傳回值的方法,其第一個參數的類型為 Object,它引用引發事件的執行個體,第二個參數從 EventArgs 類型派生,它儲存事件數目據。 如果事件不建置事件資料,則第二個參數只是 EventArgs 的一個執行個體。 否則,第二個參數為從 EventArgs 派生的自訂類型,提供儲存事件數目據所需的全部欄位或屬性。

EventHandler 是一種預定義委託,表示事件的事件處理常式方法,它與事件是否建置事件資料無關。 如果事件不建置事件資料,則用 EventArgs 替代泛型型別參數;否則,提供自己的自訂事件數目據類型並用該類型替代泛型型別參數。

使用 EventHandler 的優點在於,如果事件建置事件資料,則無需編寫自己的自訂委託代碼。 此外,.NET Framework 只需一個實現就能支援 EventHandler ,這與替代泛型型別參數的事件數目據類型無關。

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestEvent{public class CarInfoEventArgs:EventArgs{public CarInfoEventArgs(string car){this.Car = car;}public string Car{get; private set;}}public class CarDealer{public event EventHandlerNewCarInfo;public void NewCar(string car){Console.WriteLine("CarDealer. new car {0}", car);if (NewCarInfo != null){NewCarInfo(this, new CarInfoEventArgs(car));}}}}

事件監聽器:Consumer類用作事件接聽程式。這個類訂閱了CarDealer類的事件,並定義了NewCarIsHere方法,該方法滿足EventHandler委託的要求,其參數類型是object和CarInfoEventArgs.

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestEvent{class Consumer{private string name;public Consumer(string name){this.name = name;}public void NewCarIsHere(object sender, CarInfoEventArgs e){Console.WriteLine("{0}: car {1} is new", name, e.Car);}}}

現在需要串連事件發布器和訂閱器。使用“+=”建立一個訂閱。使用“-=”取消了訂閱。使用代碼:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestEvent{class Program{static void Main(string[] args){var dealer = new CarDealer();var michael = new Consumer("Michael");dealer.NewCarInfo += michael.NewCarIsHere;dealer.NewCar("Mercedes");var nick = new Consumer("Nick");dealer.NewCarInfo += nick.NewCarIsHere;dealer.NewCar("Ferrari");dealer.NewCarInfo -= michael.NewCarIsHere;dealer.NewCar("Toyota");}}}/*-------------------------------------輸出結果:CarDealer. new car MercedesMichael: car Mercedes is newCarDealer. new car FerrariMichael: car Ferrari is newNick: car Ferrari is newCarDealer. new car ToyotaNick: car Toyota is new---------------------------------------*/

淺析C#中的事件

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.