//定義一個委託,接受2個decimal類型的參數 public delegate void PirceChangedHandler(decimal oldPirce, decimal newPrice); public class Broadcaster { //定一個PirceChanged事件 public event PirceChangedHandler PriceChanged; decimal _price; public decimal Price { get { return _price; } set { if (_price == value) return; decimal oldprice = _price; _price = value; if (PriceChanged != null) PriceChanged(oldprice, _price); } } }
EventArgs是爲事件傳遞信息的基類。我們可以繼承EventArgs以便於在事件觸發的時候傳遞值參數。EventArgs子類應當根據它包含的信息來命名,二維根據使用它的時間命名。一般將數據以屬性或制度字段的方式暴露給外界。
public PriceChangedEventArgs(decimal lastPrice, decimal newPrice) { LastPrice = lastPrice; NewPrice = newPrice; }
定義了EvaenArgs子類以後,下一步就要定義事件的委託了,委託必須滿足下面三個條件:
- 委託必須以void作爲返回值。
- 委託必須接受兩個參數。第一個參數是object類型,第二個參數是EventArgs子類。第一個參數表明了時間的廣播者,第二個參數包含了需要傳遞的信息。
- 委託的名稱必須以EventHandler結尾。
public delegate void PriceChangedEventHandler(object sender, PriceChangedEventArgs e);
框架定義了一個名爲System.EventHandler<>的泛型委託也滿足以上三個條件:
public class Stock { public event EventHandler<PriceChangedEventArgs> PriceChanged; protected virtual void OnPriceChanged(PriceChangedEventArgs e) { var temp = PriceChanged;//爲了多線程下可靠的工作,在測試和調用委託之前需要將他保存到零時變量 if (temp != null) temp(this, e); PriceChanged?.Invoke(this, e);//也可以這麼寫,線程安全又書寫簡單,是最好的觸發方式。 } }
完整的代碼如下:
public class PriceChangedEventArgs : System.EventArgs { public readonly decimal LastPrice; public readonly decimal NewPrice; public PriceChangedEventArgs(decimal lastPrice, decimal newPrice) { LastPrice = lastPrice; NewPrice = newPrice; } } public class Stock { public event EventHandler<PriceChangedEventArgs> PriceChanged; protected virtual void OnPriceChanged(PriceChangedEventArgs e) { //爲了多線程下可靠的工作,調用委託之前需要將他保存到零時變量 //var temp = PriceChanged; //if (temp != null) // temp(this, e); PriceChanged?.Invoke(this, e);//也可以這麼寫,線程安全又書寫簡單,是最好的觸發方式。 } decimal price; public decimal Price { get { return price; } set { if (price == value) return; decimal priceold = price; price = value; OnPriceChanged(new PriceChangedEventArgs(priceold, price)); } } } using App; Stock stock = new Stock(); stock.Price = 20; stock.PriceChanged += Stock_PriceChanged; for (int i = 0; i < 10; i++) { stock.Price = i + 20; Task.Delay(1000).Wait(); } void Stock_PriceChanged(object? sender, PriceChangedEventArgs e) { Console.WriteLine($"當前價格:{e.NewPrice},上一次的價格{e.LastPrice}"); } Console.ReadKey();
和方法一樣,事件也可以重寫,可以是虛的,抽象的密封的,靜態的。