事件 event

事件 event
  1 using System;
  2 
  3 namespace ConsoleApp1
  4 {
  5     class Program
  6     {
  7         static void Main(string[] args)
  8         {
  9             Stock stock = new Stock("cmp");
 10             stock.Price = 27.10M;
 11             stock.PriceChanged += stock_PriceChanged;
 12             stock.Price = 31.59M;
 13         }
 14 
 15         static void stock_PriceChanged(object sender, PriceChangedEventArgs e)
 16         {
 17             if ((e.NewPrice - e.LastPrice / e.LastPrice) > 0.1M)
 18             {
 19                 Console.WriteLine("Alert, 10% stock price increse! ");
 20             }
 21         }
 22     }
 23     /**
 24      * .NET Framework 为 事件编程定义了一个标准模式,它的目的就是保持框架和用户代码的一致性。
 25      * 标准事件模式的核心是System.EventArgs类,一个预定义的没有成员(但是有一个静态的Empty属性)的类。EventArgs
 26      * 是为事件传递信息的基类。在Stock示例中,我们可以继承EventArgs以便在PriceChanged事件触发时
 27      * 传递新的和旧的Price值:
 28      */
 29     public class PriceChangedEventArgs : System.EventArgs
 30     {
 31         public readonly decimal LastPrice;
 32         public readonly decimal NewPrice;
 33 
 34         public PriceChangedEventArgs(decimal lastPrice, decimal newPrice)
 35         {
 36             LastPrice = lastPrice;
 37             NewPrice = newPrice;
 38         }
 39     }
 40 
 41     /**
 42      * EventArgs子类就位后,下一步就是选择或者定义事件的委托了。这一步需要遵循三条规则:
 43      * 1. 委托必须以void作为返回值。 
 44      * 2. 委托必须接受两个参数,第一个参数是object类型,第二个参数则是EventArgs的子类。
 45      *    第一个参数表明了事件的广播者,第二个参数则包含了需要传递的额外信息。
 46      * 3. 委托的名称必须以EventHandler结尾。框架定义了一个名为 System.EventHandler<>的泛型委托,该委托满足以上提到
 47      *    的三个条件:
 48      */
 49 
 50 
 51     //出于历史原因,框架中的大部分事件使用委托是这样定义的。
 52     // public delegate void PriceChangedHandler(object sender, PriceChangedEvetArgs e);
 53 
 54     public class Stock
 55     {
 56         string symbol;
 57         decimal price;
 58         public Stock(string symbol)
 59         {
 60             this.symbol = symbol;
 61         }
 62         //定义型泛型委托类型的事件,这里使用泛行的EventHander委托:
 63         public event EventHandler<PriceChangedEventArgs> PriceChanged;
 64         //编写一个protected虚方法来触发事件。方法名必须和事件名称一致以On作为前缀,并接收唯一的EventArgs参数:
 65         protected virtual void OnPriceChanged(PriceChangedEventArgs e)
 66         {
 67             PriceChanged?.Invoke(this, e);
 68         }
 69 
 70         public decimal Price
 71         {
 72             get { return price; }
 73             set
 74             {
 75                 if (price == value) return;
 76 
 77                 decimal oldPrice = price;
 78                 price = value;
 79 
 80                 OnPriceChanged(new PriceChangedEventArgs(oldPrice, price));
 81             }
 82         }
 83     }
 84 
 85 
 86     /**
 87      * 如果事件不需要传递额外的信息,则可以使用预定义的非泛型委托EventHandler。 
 88      * 本例中,我们重写Stock类,当Price属性发生变化时,
 89      * 触发PriceChanged事件,事件除了传达已发生的消息之外没有必须包含的信息。
 90      * 为了避免创建非必要的EventArgs实例,我们使用 了EventArgs.Emtpy属性:
 91      */
 92 
 93     public class Stock_Empty
 94     {
 95         string symbol;
 96         decimal price;
 97         public Stock_Empty(string symbol) { this.symbol = symbol; }
 98 
 99         public event EventHandler PriceChanged;
100         protected virtual void OnPriceChanged(EventArgs e)
101         {
102             PriceChanged?.Invoke(this, e);
103         }
104         public decimal Price
105         {
106             get { return price; }
107             set
108             {
109                 if (price == value) return;
110 
111                 price = value;
112                 OnPriceChanged(EventArgs.Empty);
113             }
114         }
115     }
116 
117 }
View Code

参考:约瑟夫·阿坝哈瑞(Joseph Albahari); 本·阿坝哈瑞(Ben Albahari). C# 7.0核心技术指南(原书第7版) (O’Reilly精品图书系列) (Kindle位置3328). 北京华章图文信息有限公司. Kindle 版本. 

上一篇:decimal类型 MysqlDataTruncation: Data truncation: Out of range value for column ‘unit_price‘ at row 1


下一篇:Python解析博客园备份的XML文件