CLR via C#(第3版):事件学习(一)
本篇以一个案例学习了事件定义的整个过程,如下
第一步:定义类型来容纳所有需要发送给事件通知接收者的附加信息
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace EventDemo { //第一步:定义类型来容纳所有需要发送给事件通知接收者的附加信息 //注意NewMailEventArgs继承制EventArgs class NewMailEventArgs:EventArgs { //注意:私有字段是readonly private readonly string strFrom; private readonly string strTo; private readonly string strSubject; public NewMailEventArgs(string from,string to,string subject) { strFrom = from; strTo = to; strSubject = subject; } //注意:属性也是只读的 public string From { get{return strFrom;} } public string To { get { return strTo; } } public string Subject { get { return strSubject; } } } }
第二步:定义事件成员
第三步:定义负责引发事件的方法通知事件的登记对象
第四步:定义方法将输入转化为期望事件
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace EventDemo { /// <summary> /// 负责接收传入的电子邮件 /// </summary> class MailManager { //第二步:定义事件成员 //公开一个名为NewMail事件,其他类型(Fax,Paper)的对象可以登记他们对这个事件的关注 //MailManageer收到一封电子邮件时会引发该事件,造成邮件分发给每个已登记的对象,每个对象用他们自己的方式处理该邮件 //事件成员的组成: //(1)访问修饰符public(几乎肯定是public,这样其他的代码才可能访问该事件成员) //(2)event关键字 //(3)委托类型(它指出要调用的方法的原型),这里的EventHandler<TEventArgs>的方法原型为(object sneder,NewMailEventArgs e) //(4)一个名称(任意的有效的标识符) public event EventHandler<NewMailEventArgs> NewMail; //第三步:定义负责引发事件的方法通知事件的登记对象 //该方法默认实现只检查一下是否有对象登记了对事件的关注 protected virtual void OnNewMail(NewMailEventArgs e) { //出于线程安全的考虑,现在将对委托字段的引用复制到一个临时字段中 EventHandler<NewMailEventArgs> temp = Interlocked.CompareExchange(ref NewMail, null, null); //任何方法登记了对事件的关注就通知它们 if (temp != null) temp(this, e); } //第四步:定义方法将输入转化为期望事件 //获取一些输入,并把它转化为事件的引发. //SimulateNewMail来指出一封新单额电子邮件已到达MailManager //SimulateNewMail收到一些关于邮件的信息,并构造一个NewMailEventArgs对象,将邮件信息传给它的构造器。 //然后调用MailManger自己的虚方法OnNewMail来正式通知MailManager对象收到新的电子邮件 . //这会导致事件的引发,从而通知所有登记的方法。(如前所述MainManager派生类可以重写这个方法) public void SimulateNewMail(string from, string to, string subject) { NewMailEventArgs e=new NewMailEventArgs(from ,to ,subject); OnNewMail(e); } } }
最后设计侦听事件的类
(1)Papaer类
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace EventDemo { //设计侦听事件的类Paper sealed class Paper { //将MailManager对象传给构造器 public Paper(MailManager mm) { //构造EventHandler<NewMailEventArgs>委托的一个实例 //使它引用我们的FaxMsg回调方法 //向MailManager的NewMail事件登记我们的回调方法(方法登记对该事件的关注) mm.NewMail += PaperMsg; } //新电子邮件到达时,MailManager将调用这个方法 private void PaperMsg(object sender, NewMailEventArgs e) { //sender表示MailManager对象,便于将信息传回给它 //e表示MailManager对象想传给我们的附加事件信息 Console.WriteLine("Papering mail message:"); Console.WriteLine("From{0},To{1},Subject{2}", e.From, e.To, e.Subject); } //执行这个方法,Fax对象将向NewMail事件注销自己对它的关注 public void UnRegister(MailManager mm) { //向MailManager的NewMail事件注销自己对这个事件的关注(方法取消对事件的关注) mm.NewMail -=PaperMsg; } } }
(2)Fax类
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace EventDemo { //设计侦听事件的类Paper sealed class Fax { public Fax(MailManager mm) { mm.NewMail += FaxMsg; } private void FaxMsg(object sender, NewMailEventArgs e) { Console.WriteLine("Faxing mail message:"); Console.WriteLine("From{0},To{1},Subject{2}", e.From, e.To, e.Subject); } public void UnRegister(MailManager mm) { mm.NewMail -= FaxMsg; } } }
浙公网安备 33010602011771号