事件,人们事先规定好的一个动作,当我们做了某件事时,会触发该动作的发生。在win32/mfc中我们利用事先定义的宏和回调函数来完成这些内容。自己定义的事件,主要明确两件事情:1、要发生的动作,这个需要我们自己来定义;2、就是触发,就是在适当的时机调用该自己定义的动作。
因此我们在设计类时,定义委托(类似于C的回调函数),把委托作为我们要调用的函数来处理,在某些动作完成时调用委托。此时我们并不知道会调用什么函数,只知道当完成某一动作时需要出发委托函数。而当用户使用该类的时候就方便了,我们只需要定义自己的动作,并把它添加到委托中,即可完成事件机制。
但是,为了统一标准,提供框架和用户代码的一致性,.net框架为编写事件代码定义了标准模式。event关键字就是委托的包装器,只是公开了广播器和接受器模块的委托属性的子集,主要是为了降低接受器之间的相互干扰(接收器不可使用 +=运算符来修改委托,将委托指定为null,再次通过委托广播等)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StandardEvent
{
class PriceChangedEventArgs : EventArgs
{
public readonly decimal LastPrice;
public readonly decimal NewPrice;
public PriceChangedEventArgs(decimal lp, decimal np)
{
LastPrice = lp;
NewPrice = np;
}
}
class Stock//即是广播又是接收
{
decimal price;
//string symbol = "stock";
public event EventHandler<PriceChangedEventArgs> PriceChanged;
public decimal Price{
get { return price; }
set {
if(price != value)
{
OnPriceChanged(new PriceChangedEventArgs(price, value));//事件触发
}
price = value;
}
}
protected virtual void OnPriceChanged(PriceChangedEventArgs e)
{
if (PriceChanged != null)
PriceChanged(this, e);
}
}
class Program
{
static void priceChangeInMain(Object sender, PriceChangedEventArgs e)
{
System.Console.WriteLine(sender.ToString());
System.Console.WriteLine("last price" + e.LastPrice + "\nnew price" + e.NewPrice);
}
static void Main(string[] args)
{
Stock s = new Stock();
s.Price = 100M;//这时没有调用priceChangeInMain,因为没有添加事件
s.PriceChanged += priceChangeInMain;
s.Price = 200M;//添加完事件之后的触发调用了priceChangeInMain
}
}
}