本文是学习C#高级编程和C#入门经典的一点记录。
理解事件这个东西,必须先知道委托。 事件基于委托。事件是提供了发布/订阅机制的委托。
事件是由对象引发的,我们可以提供代码来处理事件。我们需要在代码中订阅(subscribe)事件才能在事件发生时执行这些代码,即设置事件处理程序。
单个事件可以有多个时间处理程序。在该事件发生后,这些处理程序都会被调用。时间处理程序可以在引发该事件的对象所在的类中,也可以在其他类中。事件的处理程序本身都是简单的方法,对事件处理方法唯一的要求是他必须匹配事件所要求的返回类型和参数。
事件的基本处理过程是这样的。首先,应用程序创建一个可引发事件的对象。接着,应用程序订阅该事件。当事件引发后,就会通知订阅器执行相应的时间处理程序。
下面是一个直接连接事件发布程序和订阅器的事件的例子,这种连接方式叫做强连接。这个例子中CarDealer类提供一个新车到达时触发的事件。Customer类订阅该事件,以获得新车到达时的通知。
首先,定义事件的发布程序:
public class CarInfoEventArgs : EventArgs//作为事件的参数,必须派生自EventArgs基类 { public CarInfoEventArgs(string car) { this.Car = car; } public string Car { get; private set; } } public class CarDealer { public event EventHandler<CarInfoEventArgs> NewCarInfo;//定义事件 public void NewCar(string car) { Console.WriteLine("CarDealer, new car {0}", car); if (NewCarInfo != null) { NewCarInfo(this, new CarInfoEventArgs(car));//触发事件 } } }
CarDealer类用event关键字定义类类型为EventHandler<CarInfoEventArgs>的事件 NewCarInfo。在NewCar方法中触发该事件。
事件一般使用带两个参数的方法,第一个参数是一个包含事件发布者的对象。第二个参数提供类事件的相关信息。第二个参数随着事件类型的不同而不同。但第二个参数的类型必须派生自EventArgs类。这是约定,只有满足了这些的程序才能作为事件的处理程序,需要牢记。
第二步,在类Customer中订阅该事件
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); } }
Customer类用做事件侦听程序,这个类订阅了CarDealer类的时间。并定义了满足EventHandler<CarInfoEventArgs>委托要求的NewCarIsHere方法
之后就可以连接事件发布程序和事件订阅器了:
static void Main() { var dealer = new CarDealer(); var michael = new Consumer("Michael"); dealer.NewCarInfo += michael.NewCarIsHere; dealer.NewCar("Mercedes"); var nick = new Consumer("Nick"); dealer.NewCarInfo += nick.NewCarIsHere; dealer.NewCar("Ferrari"); dealer.NewCarInfo -= michael.NewCarIsHere; dealer.NewCar("Toyota"); }
运行该程序,Michael首先订阅了NewCarInfo 事件(dealer.NewCarInfo += michael.NewCarIsHere;)当一辆Mercedes到达时,Michael会得到通知。
之后Nick也订阅了该事件(dealer.NewCarInfo += nick.NewCarIsHere;),当一辆Ferrari到达时,Michael和Nick都会获得通知。
后来michael取消了对该事件的订阅(dealer.NewCarInfo -= michael.NewCarIsHere;),当一辆Toyota到达时,之后Nick会得到通知,而Michael不会得到通知。
至此,事件的整个处理过程完成了。
这个例子中,通过事件直接连接了发布程序和订阅器。但这样的连接方式会对垃圾回收造成一些困难。要解决这个困难,需要使用弱事件模式来解决。即使用WeekEventManager作为事件发布程序和侦听器之间的中介。这有点麻烦,我还不是很理解,先不写了。
总结一下:
1、事件是一种委托。我把事件理解为由系统定义的EventHandler<T>泛型的委托。该委托需要的两个参数类型分别为object和T。T必须派生自基类EventArgs
2、事件的处理过程是:发布-订阅模式。
3、可以通过+=、-=创建订阅和取消订阅。
最后,祝新年快乐。也祝我自己在新的一年中成为编程高手。
11年12月3号,编辑了代码的显示