C# 事件

2018-01-16 02:34 更新

C#事件

事件系統(tǒng)是軟件系統(tǒng)的核心部分。例如,按鈕可以觸發(fā)點(diǎn)擊事件。批處理作業(yè)可以生成作業(yè)完成事件。學(xué)生系統(tǒng)將使用注冊事件。

廣播者是包含委托字段的類型。

廣播者決定何時(shí)廣播,通過調(diào)用委托。

訂閱者是方法目標(biāo)收件人。

訂閱者通過在廣播者的委托上調(diào)用+ =和 - =決定何時(shí)開始和停止偵聽。

事件是一個C#語言功能,正式化這種模式。

例子

要聲明事件,請將事件關(guān)鍵字放在代理成員的前面:

// a delegate
public delegate void ValueChangedHandler (decimal oldPrice, decimal newPrice);

public class Broadcaster {
   // Event declaration
   public event ValueChangedHandler PriceChanged;
}

Broadcaster 類型中的代碼具有對 PriceChanged 的完全訪問權(quán)限,可以將其視為代理。

Broadcaster 外部的代碼只能對PriceChanged 事件執(zhí)行+ =和 - =操作。


標(biāo)準(zhǔn)事件模式

.NET Framework定義了用于寫入事件的標(biāo)準(zhǔn)模式。

System.EventArgs是一個沒有成員的預(yù)定義的Framework類。

EventArgs 是一個承載事件信息的基類。

以下代碼將 EventArgs 子類化,以啟動PriceChanged 事件時(shí)存儲舊價(jià)格和新價(jià)格:

public class PriceChangedEventArgs : System.EventArgs {
    public readonly decimal LastPrice;
    public readonly decimal NewPrice;
    public PriceChangedEventArgs (decimal lastPrice, decimal newPrice) {
        LastPrice = lastPrice;
        NewPrice = newPrice;
    }
}

EventArgs 子類根據(jù)其包含的信息命名。

它通常將數(shù)據(jù)作為屬性或作為只讀字段公開。

創(chuàng)建 EventArgs 子類之后,下一步是為事件定義一個委托,它是事件處理程序委托。

事件處理程序委托必須有一個void返回類型。

事件處理程序委托必須接受兩個參數(shù):第一個是類型對象,第二個是EventArgs的子類。

第一個參數(shù)指示事件廣播者,第二個參數(shù)包含要傳達(dá)的額外信息。

事件處理程序委托的名稱必須以 EventHandler 結(jié)尾。

框架定義了一個稱為 System.EventHandler<> 的通用委托,它滿足這些規(guī)則:


public 
delegate 
void 
EventHandler<TEventArgs> (object source, TEventArgs e) 
where TEventArgs : EventArgs;

以下代碼定義了我們的值更改事件的委托。

public delegate void ValueChangedHandler (object sender, PriceChangedEventArgs e);

下一步是定義所選委托類型的事件。

在這里,我們使用通用 EventHandler 委托:

public class Product {
    public event EventHandler<PriceChangedEventArgs> PriceChanged;
}

最后,該模式需要您編寫一個受保護(hù)的虛擬方法來觸發(fā)事件。

該名稱必須與事件的名稱匹配,前綴為單詞On,并接受單個EventArgs參數(shù):

public class Product {
    ...
    public event EventHandler<PriceChangedEventArgs> PriceChanged;
    protected virtual void OnPriceChanged (PriceChangedEventArgs e) {
        if (PriceChanged != null) PriceChanged (this, e);
    }
}

例2

這里是完整的例子:


using System;

public class PriceChangedEventArgs : EventArgs {
    public readonly decimal LastPrice;
    public readonly decimal NewPrice;

    public PriceChangedEventArgs (decimal lastPrice, decimal newPrice) {
        LastPrice = lastPrice; NewPrice = newPrice;
    }
}

public class Product {
    string symbol;
    decimal price;

    public Product (string symbol) {
       this.symbol = symbol;
    }
    
    public event EventHandler<PriceChangedEventArgs> PriceChanged;
    
    protected virtual void OnPriceChanged (PriceChangedEventArgs e) {
        if (PriceChanged != null) {
           PriceChanged (this, e);
        }
    }
    public decimal Price {
       get { 
          return price; 
       }
       set {
         if (price == value) return;
         decimal oldPrice = price;
         price = value;
         OnPriceChanged (new PriceChangedEventArgs (oldPrice, price));
      }
    }
}
class Test {
     static void Main()  {
        Product stock = new Product ("THPW");
        stock.Price = 2.10M;
        // Register with the PriceChanged event
        stock.PriceChanged += stock_PriceChanged;
        stock.Price = 3.9M;
     }
     static void stock_PriceChanged (object sender, PriceChangedEventArgs e) {
         if (e.NewPrice - e.LastPrice > 0){
             Console.WriteLine ("Alert!");
         }
     }
}

事件訪問器和修飾符

事件的訪問器是其 + = - = 函數(shù)。

默認(rèn)情況下,訪問器由編譯器隱式實(shí)現(xiàn)。

像方法一樣,事件可以是虛擬的,重寫的,抽象的或密封的。

事件也可以是靜態(tài)的:


public class Product {
    public static event EventHandler<EventArgs> StaticEvent;
    public virtual event EventHandler<EventArgs> VirtualEvent;
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號