C# 標準事件模式
阿新 • • 發佈:2018-05-07
bject 返回值 不必要 virt void ret last AS str
.NET框架為事件定義了一個標準模式,它的目的是保持框架和用戶代碼之間的一致性。
標準事件的模式核心是SystemEventArgs——預定義的沒有成員的框架類(不同於靜態Empty屬性)
EventArgs表示包含事件數據的類的基類,並提供用於不包含事件數據的事件的值。用於為事件傳遞信息的基類。
在下面例子中,我們定義EventArgs的子類,用於事件PriceChanged被引發時,傳遞新舊Price值:
public class PriceChangedEventArgs : EventArgs
{
public readonly decimal LastPrice;
public readonly decimal NewPrice;
public PriceChangedEventArgs(decimal lastPrice, decimal newPrice)
{
LastPrice=lastPrice;
NewPrice= newPrice;
}
}
考慮到復用性,EventArgs子類根據它包含的內容命名(而非根據將被使用的事件命名)。
選擇或定義事件的委托,需遵循三條原則:
- 委托必須以void作為返回值
- 委托必須接受兩個參數:第一個是object類,第二個是EventArgs的子類。
- 委托的名稱必須以EventHandler結尾
完整例子:
class Test
public static void Main()
{
InitializeComponent();
Stock stock = new Stock("THPW");
stock.Price = 27.10M;
//註冊PriceChanged事件
stock.PriceChanged += stock_PriceChanged;
stock.Price = 31.59M;
}
static void stock_PriceChanged(object sender, PriceChangedEventArgs e)
{
if ((e.NewPrice - e.LastPrice) / e.LastPrice > 0.1M)
{
Console.WriteLine("Alert,10% stock increase!");
}
}
}
public class Stock
{
string symbol;
decimal price;
public Stock(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;
price = value;
OnPriceChanged(new PriceChangedEventArgs(price, value)); } } } public class PriceChangedEventArgs : EventArgs { public readonly decimal LastPrice; public readonly decimal NewPrice; public PriceChangedEventArgs(decimal lastPrice, decimal newPrice) { LastPrice=lastPrice; NewPrice= newPrice; } }
如果事件不傳遞額外的信息,可以使用預定義的非泛化委托EventHandler。如下所示:
class Test
{
public static void Main()
{
InitializeComponent();
Stock stock = new Stock();
stock.Price = 27.10M;
//註冊PriceChanged事件
stock.PriceChanged += stock_PriceChanged;
stock.Price = 31.59M;
}
static void stock_PriceChanged(object sender, EventArgs e)
{
Console.WriteLine("價格變換了!");
}
}
public class Stock
{
decimal price;
public event EventHandler PriceChanged;
protected virtual void OnPriceChanged(EventArgs e)
{
if (PriceChanged != null) PriceChanged(this, e);
}
public decimal Price
{
get { return price; }
set
{
if (price == value) return;
price = value;
//OnPriceChanged(new EventArgs());
OnPriceChanged(EventArgs.Empty);
}
}
}
註意:
上面例子中事件除了傳遞已發生信息,沒有傳遞其他信息。
你可以使用 OnPriceChanged(new EventArgs()) 來完成事件的傳遞。
為了避免對EventArgs不必要的初始化,建議使用EventArgs.Empty屬性。使用這樣一個“空的”靜態引用的對象,避免多余地去創建一個新對象。
微軟的大部分控件所拋出的事件都有兩個參數,第一個是 object 類型的,第二個是 EventArgs 類型的。
你從EventArgs e那裏得不到任何此次事件相關需要傳遞的信息,真正傳遞的信息都在sender中。
C# 標準事件模式