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

    事件的标准模式

    .NET 框架为事件编程定义了一个标准模式。设定这个标准是为了让.NET框架和用户代码保持一致。System.EventArgs是标准模式的核心,它是一个没有任何成员,用于传递事件参数的基类。
    按照标准模式,我们对于上面的iPhone6示例进行重写。首先定义EventArgs:

    public class PriceChangedEventArgs : EventArgs {
        public readonly decimal OldPrice;
        public readonly decimal NewPrice;
        public PriceChangedEventArgs(decimal oldPrice, decimal newPrice) {
            OldPrice = oldPrice;
            NewPrice = newPrice;
        }
    }

    然后为事件定义委托,必须满足以下条件:

    • 必须是 void 返回类型;
    • 必须有两个参数,且第一个是object类型,第二个是EventArgs类型(的子类);
    • 它的名称必须以EventHandler结尾。

    由于考虑到每个事件都要定义自己的委托很麻烦,.NET 框架为我们预定义好一个通用委托System.EventHandler<TEventArgs>:

    public delegate void EventHandler<TEventArgs> (object source, TEventArgs e) where TEventArgs : EventArgs;

    如果不使用框架的EventHandler<TEventArgs>,我们需要自己定义一个:

    public delegate void PriceChangedEventHandler (object sender, PriceChangedEventArgs e);

    如果不需要参数,可以直接使用EventHandler(不需要<TEventArgs>)。有了EventHandler<TEventArgs>,我们就可以这样定义示例中的事件:

    public class IPhone6 {
        //...
        public event EventHandler<PriceChangedEventArgs> PriceChanged;
        //...
    }

    最后,事件标准模式还需要写一个受保护的虚方法来触发事件,这个方法必须以On为前缀,加上事件名(PriceChanged),还要接受一个EventArgs参数,如下:

    public class IPhone6 {
        //...
        public event EventHandler<PriceChangedEventArgs> PriceChanged;
        protected virtual void OnPriceChanged(PriceChangedEventArgs e) {
            if (PriceChanged != null) PriceChanged(this, e);
        }
        //...
    }

    下面给出完整示例:

    public class PriceChangedEventArgs : System.EventArgs {
        public readonly decimal OldPrice;
        public readonly decimal NewPrice;
        public PriceChangedEventArgs(decimal oldPrice, decimal newPrice) {
            OldPrice = oldPrice;
            NewPrice = newPrice;
        }
    }
    public class IPhone6 {
        decimal price;
        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;
                decimal oldPrice = price;
                price = value;
                // 如果调用列表不为空,则触发。
                if (PriceChanged != null)
                    OnPriceChanged(new PriceChangedEventArgs(oldPrice, price));
            }
        }
    }
    class Program {
        static void Main() {
            IPhone6 iphone6 = new IPhone6() { Price = 5288M };
            // 订阅事件
            iphone6.PriceChanged +=iphone6_PriceChanged;
            // 调整价格(事件发生)
            iphone6.Price = 3999;
            Console.ReadKey();
        }
        static void iphone6_PriceChanged(object sender, PriceChangedEventArgs e) {
            Console.WriteLine("年终大促销,iPhone 6 只卖 " + e.NewPrice + " 元, 原价 " + e.OldPrice + " 元,快来抢!");
        }
    }
    View Code

    运行结果:

  • 相关阅读:
    c:forTokens标签循环输出
    jsp转long类型为date,并且格式化
    spring中@Param和mybatis中@Param使用区别(暂时还没接触)
    734. Sentence Similarity 有字典数组的相似句子
    246. Strobogrammatic Number 上下对称的数字
    720. Longest Word in Dictionary 能连续拼接出来的最长单词
    599. Minimum Index Sum of Two Lists两个餐厅列表的索引和最小
    594. Longest Harmonious Subsequence强制差距为1的最长连续
    645. Set Mismatch挑出不匹配的元素和应该真正存在的元素
    409. Longest Palindrome 最长对称串
  • 原文地址:https://www.cnblogs.com/XiaoRuLiang/p/12431494.html
Copyright © 2011-2022 走看看