标签:
事件基于多播委托的特性。
多播委托事实上就是一组类型安全的函数指针管理器,调用则执行顺序跳转到数组里所有的函数指针里执行。
class Program { public class CarInfoEventArgs : EventArgs { public string Car { get; set; } public CarInfoEventArgs(string car) { this.Car = car; } } public class CarDealer { public event EventHandler<CarInfoEventArgs> NewCarInfo; //使用系统定义的泛型委托 public void NewCarcComing(string car) { Console.WriteLine("CarDealer, new car {0} has come.", car); EventHandler<CarInfoEventArgs> newCarInfo = NewCarInfo; if (newCarInfo != null) NewCarInfo(this, new CarInfoEventArgs(car)); } } public class Consumer { private string name; public Consumer(string name) { this.name = name; } public void NewCarIsHere(object sender, CarInfoEventArgs e) { Console.WriteLine("{0}, car {1} is new", name, e.Car); } } static void Main(string[] args) { var dealer = new CarDealer(); var personA = new Consumer("personA"); dealer.NewCarInfo += personA.NewCarIsHere; dealer.NewCarcComing("Ferrari"); var personB = new Consumer("personB"); dealer.NewCarInfo += personB.NewCarIsHere; dealer.NewCarcComing("BMW"); Console.ReadLine(); } }
基于该例,我们用“多播委托”的概念来重写:
class Program { public class CarDealer { public Action<string> NewCarInfo; //使用系统定义的泛型委托 public void NewCarComing(string car) { Console.WriteLine("CarDealer, new car {0} has come.", car); if (NewCarInfo != null) NewCarInfo(car); } } public class Consumer { private string name; public Consumer(string name) { this.name = name; } public void NewCarIsHere(string car) { Console.WriteLine("{0}, car {1} is new", name, car); } } static void Main(string[] args) { var dealer = new CarDealer(); var personA = new Consumer("personA"); dealer.NewCarInfo += personA.NewCarIsHere; dealer.NewCarComing("Ferrari"); var personB = new Consumer("personB"); dealer.NewCarInfo += personB.NewCarIsHere; dealer.NewCarComing("BMW"); Console.ReadLine(); } }
我只想知道,在多播委托的基础上,事件有哪些自身的特性?从以上两个例子中似乎看不出来。
继续来看下一个例子:
class Program { public class CarDealer { public event Action<string> NewCarInfo; //使用系统定义的泛型委托 public void NewCarComing(string car) { Console.WriteLine("CarDealer, new car {0} has come.", car); if (NewCarInfo != null) NewCarInfo(car); } } public class Consumer { private string name; public Consumer(string name) { this.name = name; } public void NewCarIsHere(string car) { Console.WriteLine("{0}, car {1} is new", name, car); } } static void Main(string[] args) { var dealer = new CarDealer(); var personA = new Consumer("personA"); dealer.NewCarInfo += personA.NewCarIsHere; dealer.NewCarInfo("Ferrari"); var personB = new Consumer("personB"); dealer.NewCarInfo += personB.NewCarIsHere; dealer.NewCarInfo("BMW"); Console.ReadLine(); } }
1. 我们在委托之前加上“event”关键字;
2. 我们在外部直接调用 委托实例;
这个例子是编译不过的,由此可知 “event” 是不能直接由外部访问的。将该实例的 “event” 关键字拿掉,则可以编译通过。
class Program { public class CarDealer { public event Action<string> NewCarInfo; //使用系统定义的泛型委托 public void NewCarComing(string car) { Console.WriteLine("CarDealer, new car {0} has come.", car); if (NewCarInfo != null) NewCarInfo(car); } } public class Consumer { private string name; public Consumer(string name) { this.name = name; } public void NewCarIsHere(string car) { Console.WriteLine("{0}, car {1} is new", name, car); } } static void Main(string[] args) { var dealer = new CarDealer(); var personA = new Consumer("personA"); dealer.NewCarInfo += personA.NewCarIsHere; dealer.NewCarComing("Ferrari"); var personB = new Consumer("personB"); dealer.NewCarInfo += personB.NewCarIsHere; dealer.NewCarComing("BMW"); Console.ReadLine(); } }
将 dealer.NewCarInfo("BMW");
改为了 dealer.NewCarComing("BMW");
则可以编译通过,说明:委托实例是可以直接调用委托方法的,而事件则需要进一步封装,由此可知,事件是将委托方法私有化的封装。
再通过 反编译器 检查exe:
可以看到,增加了 add_NewCarInfo, remove_NewCarInfo 两个方法,则进一步证明了我们对事件的定义:编译器生成了两个公有方法,来解决私有化委托后,外部无法为其增加或减少委托方法的问题。
标签:
原文地址:http://www.cnblogs.com/Daniel-Liang/p/5754427.html