zoukankan      html  css  js  c++  java
  • C# 标准事件模式

    .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中。

  • 相关阅读:
    定时器与休眠
    进程的创建
    详述进程创建和程序执行
    线程
    会话,进程组,作业控制
    进程优先级和调度
    进程资源
    日志信息log
    能力
    浅谈产品模型(Profile)在程序设计中的作用
  • 原文地址:https://www.cnblogs.com/LemonFive/p/9002239.html
Copyright © 2011-2022 走看看