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;
        }
    }
}

 代码下载

posted @ 2012-07-04 08:21  焦涛  阅读(231)  评论(0)    收藏  举报