using System;
// 标准事件模式
namespace CSspace
{
// EventArgs是为事件传递信息的基类,一个预定义的没有成员(但是有一个静态的Empty属性)的类。
// 考虑到复用性,EventArgs子类应当根据它包含的信息来命名(而非根据使用它的事件命名)。
// 它一般将数据以属性或只读字段的方式暴露给外界。
/*------------首先定义一个EventArgs的子类----------------------------------------------*/
public class WatchEventArgs:EventArgs{
public readonly Int32 OldValue;
public readonly Int32 NewValue;
public WatchEventArgs(Int32 oldValue,Int32 newValue){
this.OldValue = oldValue;
this.NewValue = newValue;
}
}
/*-------------EventArgs子类就位后,下一步就是选择或者定义事件的委托了-----*/
public class SuperStock{
Int32 stockNum;
public SuperStock(Int32 num){
stockNum = num;
}
public Int32 StockNum{
get{return stockNum;}
set{
if(stockNum == value) return;
Int32 lastNum = stockNum;
stockNum = value;
// 属性过滤中触发事件
OnwatchEvent(new WatchEventArgs(lastNum,stockNum));
}
}
// 定义事件的委托需要遵循三条规则:
// 1:委托必须以void作为返回值。(委托以void作为返回值,可使用null条件运算符,
// 但我不清楚是不为了用这个而专门设计的)
// 2:委托必须接受两个参数
// · 第一个参数是object类型,表明了事件的广播者。
// · 第二个参数则是EventArgs的子类,包含了需要传递的额外信息。
// 3:委托的名称必须以EventHandler结尾。
// 框架内置了一个名为System.EventHandler<>的泛型委托,该委托满足以上提到的三个条件:
public event EventHandler<WatchEventArgs> WatchEvent;
/*--------------最后,该模式需要编写一个protected的虚方法来触发事件------------------*/
// 该模式需要编写一个protected的虚方法来触发事件。
// 方法名必须和事件名称一致,以On作为前缀,并接收唯一的EventArgs参数
protected virtual void OnwatchEvent(WatchEventArgs args){
Console.WriteLine("当前剩余:"+this.StockNum);
WatchEvent?.Invoke(this,args);
}
public static void warming(object obj,WatchEventArgs args){
if(args.NewValue<10){
Console.WriteLine("当前库存不足10件,请及时补货!");
}
}
static void Main(){
SuperStock stock = new SuperStock(20);
stock.WatchEvent += warming;
for(int i=0;i<15;i++){
stock.StockNum--;
}
}
}
}