C# 事件——标准事件模式

218 阅读2分钟
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--;
             }
          }
    }

    

}