C# 标准事件模式
程序员文章站
2022-10-06 18:01:59
.NET框架为事件定义了一个标准模式,它的目的是保持框架和用户代码之间的一致性。 标准事件的模式核心是SystemEventArgs——预定义的没有成员的框架类(不同于静态Empty属性) EventArgs表示包含事件数据的类的基类,并提供用于不包含事件数据的事件的值。用于为事件传递信息的基类。 ......
.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中。