C#事件的使用(一)

==============
@ 在类中定义事件
==============

using  System;

//  Mail 管理。
class  MailManager{
    
//  1.定义事件参数,用于向事件接受者传递附加信息。
    
//  事件参数类都应该继承自 System.EventArgs,并且类型名称以 EventArgs 结束。
     public   class  MailMsgEventArgs : EventArgs{    
        
public  MailMsgEventArgs( string  from,  string  to,  string  subject,  string  body) {
            
this .from  =  from;          //  发送者。
             this .to  =  to;                 //  接受者。
             this .subject  =  subject;  //  主题。
             this .body  =  body;        //  正文。
        }
        
public   readonly   string  from, to, subject, body;
    } 

    
//  2.定义一个委托类型,用于指定事件触发时被调用的方法原型。
    
//  委托类型的名称应该以 EventHandler 结束。另外方法原型返回值应该为 void,并且有两个参数:
    
//  第一个参数指向发送通知的对象,第二个是事件参数。如果我们定义的时间没有需要传递给事件接受者
    
//  的附加信息,就不需要定义新的委托类型,直接使用 System.EventHandler,并将 EventArgs.Empty
    
//  传递给第二个参数即可。
     public   delegate   void  MailMsgEventHandler(Object sender, MailMsgEventArgs args);

    
//  3.定义事件。
    
//  如下定义的事件的名称是 MailMsg,类型为 MailMsgEventHandler,其含义为所有事件接受者都必须提供
    
//  一个原型和 MailMsgEventHandler 想匹配的方法。
     public   event  MailMsgEventHandler MailMsg;

    
//  4. 触发事件。将一些外部输入转化为触发事件的动作。
     public   void  SimulateArrivingMsg( string  from,  string  to,  string  subject,  string  body) {
        MailMsgEventArgs e 
=   new  MailMsgEventArgs(from, to, subject, body);
        
        
//  调用虚方法通知对象事件已发生,如果派生类型没有重写该虚方法,
        
//  对象将通知所有登记的时间侦听者。
        OnMailMsg(e);
    }

    
//  5.事件处理,负责通知事件的侦听者。
     protected   virtual   void  OnMailMsg(MailMsgEventArgs e) {
        
if  (MailMsg  !=   null ) {
            
//  将事件通知给委托链表上的所有对象。
            MailMsg( this , e);
        }
    }
}

 

======================
@ 编译器对事件定义语句的处理
======================

对于上面代码中的定义事件的语句:
public event MailMsgEventHandler MailMsg;
编译器会将其翻译为如下三个方法:

//  1. 一个初始化为 null 的"私有"委托类型字段。
private  MailMsgEventHandler MailMsg  =   null ;
//  2. 一个允许其他对象登记事件的"公有" add_* 方法。
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public   void  add_MailMsg(MailMsgEventHandler handler){
 
this .MailMsg  =  (MailMsgEventHandler)Delegate.Combine(MailMsg, handler);
}
//  3. 一个允许其他对象注销事件的"公有" remove_* 方法。
[MethodImplAttribute(MethodImplOptions.Sysnchronized)]
public   void  remove_MailMsg(MailMsgEventHandler handler){
 MailMsg 
=  (MailMsgEventHandler).Delegate.Remove(MailMsg, handler);
}

 

add_* 和 remove_* 方法都应用了一个 MethodImplAttribute 特性,这些方法被标识为同步方法,使得它们得以
实现线程安全:也就是多个事件侦听者可以同时登记或者注销事件,而不损坏委托链表。这两个方法的访问限制
取决于事件的访问限制,如果事件被定义为受保护事件,那么这两个方法也将为受保护方法。

============
@ 定义侦听事件的类
============

//  传真机侦听 MailManager 的 MailMsg 事件,并发送传真(输出到控制台)。
class  Fax
{
    
//  将 MailManager 对象传递给构造函数。
     public  Fax(MailManager mm) {
        
//  构造一个指向 FaxMsg 回调方法的 MailMsgEventHandler 委托实例,
        
//  然后登记 MailManager 的 MailMsg 事件。
        mm.MailMsg  +=   new  MailManager.MailMsgEventHandler(FaxMsg);
    }

    
//  MailManager 将调用该方法来通知 Fax 对象收到到一个新的电子邮件消息。
    
//  sender: 表示 MailManager 对象,如果希望和事件的触发者通信,可以使用该参数。
    
//  e:表示 MailManager 对象提供的一些附加事件信息。
     private   void  FaxMsg(Object sender, MailManager.MailMsgEventArgs e) {
        Console.WriteLine(
"  From: {0} \n To: {1} \n Subject: {2} \n Body: {3} \n "   +  
            e.from, e.to, e.subject, e.body);
    }

    
//  注销事件。
     public   void  Unregister(MailManager mm) {
        
//  创建一个新的委托实例是为了将其从委托链表中移除(参见《深入理解委托》)
        MailManager.MailMsgEventHandler callback  =   new  MailManager.MailMsgEventHandler(FaxMsg);
        mm.MailMsg 
-=  callback;
    }
}

 

========
@ 使用事件
========

using  System;

public   class  Test
{
    
public   static   void  Main( string [] args) {
        
//  定义事件发送者 mm。
        MailManager mm  =   new  MailManager();
        
        
//  定义事件侦听者,侦听 mm 发送的时间。
        Fax fax  =   new  Fax(mm);

        
//  触发事件发送者定义的事件。
        mm.SimulateArrivingMsg( " Me " " You " " Love " " I love you ! " ); 
    }
}

输出:
 From: Me
 To: You
 Subject: Love
 Body: I love you !

 

转载于:https://www.cnblogs.com/JoeDZ/archive/2008/06/29/1232005.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值