C#框架阅读--事件

来源:互联网 发布:淘宝五金冠店铺 编辑:程序博客网 时间:2024/06/05 20:19
事件
第一步:定义一个类型用于存放所有需要发送给事件通知接受者的附加信息
    按照约定,所有传递给事件处理程序的用于存放事件信息的类都应该继承自System.EventArgs,
并且类的名称应该以EventArgs结束。在本例中,NewMailEventArgs类拥有一个字段来表示消息的发送者(M-from)
消息的接受者(m_to)以及消息的主题(m_subject).

//第一步:定义一个类型用于存放所有需要发送给事件接受者的附加信息
internal class NewMailEventArgs : EventArgs
{
    private readonly String m_from, m_to, m_subject;
    
    public NewMailEventArgs(String from, String to, String subject)
    {
        m_from         = from;
        m_to        = to;
        m_subject    = subject;
    }
    
    public String From
    {
        get { return m_from;}
    }
    public String To
    {
        get { return m_to; }
    }
    public String Subject
    {
        get { return m_subject; }
    }
}

注意:类EventArgs的实现如下:
[ComVisible(true)]
[Serializable]
public class EventArgs
{
    public static readonly EventArgs Empty = new EventArgs();
    public EventArgs()
    {
    }
}

第二步:定义事件成员
    事件成员使用C#关键字event定义,每个事件成员都有一个给定的可访问性(通常都为public,以便于其他代码也可以访问这个事件成员)、
一个表示即将被调用方法的原型的委托类型以及一个名称(可以使任意有效的标示符)。NewMail类中事件成员的形式如下:

    internal class MailManager
    {
        //第二步:定义事件成员
        public event EventHandler<NewMailEventArgs> NewMail;
        ...
    }

    NewMail是事件的名称。事件成员的类型是EventHandler<NewMailEentArgs>,其含义为所有事件通知的接受者都必须提供一个原型
和EventHandlet<NewMailEventArgs>委托类型相匹配的回调方法。由于泛型System.EventHandler委托类型的定义如下:

        public delegate void EventHandler<TEventArgs>
        (Object sender, TEventArgs e) where TEventArgs: EventArgs;
        
因此方法原型必须具有下述形式:

    void MethodName(Object sender, NewMailEventArgs e);
    
第三步: 定义一个负责引发事件的方法来通知已订阅事件的对象事件已经发生

    按照约定,类应定义一个受保护的虚方法,当引发事件时,这个类及其派生类中的代码可以调用这个虚方法。该方法有一个参数,
即NewMailEventArgs对象,这一对象包含了传递给接收通知的对象的信息。它的默认实现仅仅检查是否有对象已经订阅了事件,如果
存在这种对象,则事件将被引发,因此需要通知已订阅事件的方法事件已经发生。

MailManager类中的给方法如下所示:    
    
    internal class MailManager
    {
        //第二步:定义事件成员
        public event EventHandler<NewMailEventArgs> NewMail;
        ...
        //第三步:定义一个负责引发事件的方法,来通知已订阅事件的事件已经发生。如果类是封装的,
        //则需要将方法声明为private和non-virtual
        protected virtual void OnNewMail(NewMailEventArgs e)
        {
            //出于线程安全的考虑,将委托字段保存到一个临时字段中,防止其他线程修改NewMail
            EventHandler<NewMailEventArgs> temp = NewMail;
            
            //通知所有已订阅事件的对象
            if(temp != null )
            {
                temp(this, e);
            }
        }
    }    
    
第四步:定义一个方法,将输入转化为期望事件

    在定义的类中,必须还有一些方法可以将外部的输入转化为引发事件的动作。在MailManager范例中,
调用SimulateNewMail方法表示一个新的电子邮件消息到达。
    
    internal class MailManager
    {
        //第二步:定义事件成员
        public event EventHandler<NewMailEventArgs> NewMail;
        ...
        //第三步:定义一个负责引发事件的方法,来通知已订阅事件的事件已经发生。如果累是封装的,
        //则需要将方法声明为private和non-virtual
        protected virtual void OnNewMail(NewMailEventArgs e)
        {
            //出于线程安全的考虑,将委托字段保存到一个临时字段中,防止其他线程修改NewMail
            EventHandler<NewMailEventArgs> temp = NewMail;
            
            //通知所有已订阅事件的对象
            if(temp != null )
            {
                temp(this, e);
            }
        }
        ...
        //第四步:定义一个方法,将输入转化为期望事件
        public void SimulateNewMail(String from, String to, String subject)
        {
            //构建一个对象来存放我们希望传递给通知接受者的信息
            NewMailEventArgs e = new NewMailEventArgs(from, to, subject);
            
            //调用虚方法已通知对象事件已经发生
            //如果没有对象重写该方法,那么该对象将通知所有订阅该事件的对象
            OnNewMail(e);
        }
    }    
    
    
    
    
    
    
    
    
    
    


原创粉丝点击