C#:事件

一.委托和事件:

委托的本质是一个引用数据类型
事件是一个委托的实例化对象(事件的+=和-=),这是委托和事件的本质区别

a.委托和事件的实例化应用:public delegate void VoidDelegate(),相当于声明一个voidDelegate的委托类

b.时间的定义: public event VoidDelegate MyEvent;,MyEvent是VoidDelegate的实例化对象

c.事件是基于委托的一种实现。每个事件都关联一个特定的委托类型

d.共享相同语法:事件的订阅(+=)和取消订阅(-=)操作与委托的组合(+=)和解除组合(-=)操作语法相同

e.触发机制:委托可以直接调用,无论是在类的内部还是外部,事件只能在类的内部进行调用

二.案例需求

老板向公司发邮件,每个员工需要回复收到,使用委托进行代码书写:

  //创建一个Boss类
 internal class Boss
  {
      public string BossName { get; set; }
      public Action Send; //声明一个委托,该委托无返回值委托
      //老板发布信息
      public void SendEmail() 
      {
          Console.WriteLine( "老板发送了邮件" );
          if (Send != null) 
          { 
              Send();
          
          }              
      }       
  }
//声明一个职员类
 internal class staff
 {
     public string StaffName { set; get; }
     //职员回复信息
     public void ReceiveMaiL() 
     {
         Console.WriteLine($"{StaffName}收到了邮件");
     }
 }

 //主程序入口
 static void Main(string[] args)
 {
   //实例化老板类
     Boss boss = new Boss();
     boss.BossName = "张三老板";
     //实例化多个职员类
     staff staff1 = new staff()
     { 
        StaffName= "张三"
     
      };
     staff staff2 = new staff() { StaffName="李四"};
     staff staff3 = new staff() { StaffName = "王二" };
     //对委托进行绑定
     boss.Send = staff1.ReceiveMaiL;
     boss.Send += staff2.ReceiveMaiL;
     boss.Send += staff3.ReceiveMaiL;
     boss.SendEmail();
 }

打印结果:

老板发送了邮件
张三收到了邮件
李四收到了邮件
王二收到了邮件

使用EventHandler进行代码优化,并扩展邮件内容,EventHandler是官方提供的事件处理,可以使用泛型方式 ,默认两个参数:

public delegate void EventHandler(object sender, EventArgs e);

更改上述内容如下:

//创建一个Mail类,用来储存Mail内容,时间等
internal class Mail : EventArgs //重点:该mail继承事件中的EventArgs
{
    public string content { get; set; }
    public DateTime sendTime { get; set; }
}

//创建一个Boss类 
internal class Boss
 {
     public string BossName { get; set; }
    //  public Action Send; //声明一个委托
    public EventHandler OnSend;//使用EventHandler声明,则表示,OnSend必须有两个参数
     public void SendEmail() 
     {
         Console.WriteLine( "老板发送了邮件" );
         Mail mail = new Mail()
         {
             content = "下班后开会",
             sendTime = DateTime.Now
         };
        

         if (OnSend != null) 
         { 
             OnSend(this,mail);//事件发起者为Boss,事件内容为mail
         
         }              
     }       
 }
//创建一个Staff类
 internal class staff
 {
     public string StaffName { set; get; }

     public void ReceiveMaiL(object sender, EventArgs e) //和EventHandler参数进行适配
     {
         Boss boss=sender as Boss;   //向下转型
         Mail mail=e as Mail;        //向下转型
         Console.WriteLine($"{boss.BossName}发送了邮件,发送时间:{mail.sendTime},邮件内容: 
         {mail.content},{StaffName}收到了邮件");
     }
 }
//主函数入口

static void Main(string[] args)
{
    Boss boss = new Boss();
    boss.BossName = "张三老板";
    staff staff1 = new staff()
    { 
       StaffName= "张三"
    
     };
    staff staff2 = new staff() { StaffName="李四"};
    staff staff3 = new staff() { StaffName = "王二" };
    boss.OnSend = staff1.ReceiveMaiL;
    boss.OnSend += staff2.ReceiveMaiL;
    boss.OnSend += staff3.ReceiveMaiL;
    boss.SendEmail();
}

打印结果:

老板发送了邮件
张三老板发送了邮件,发送时间:2025/5/16 10:44:28,邮件内容:下班后开会,张三收到了邮件
张三老板发送了邮件,发送时间:2025/5/16 10:44:28,邮件内容:下班后开会,李四收到了邮件
张三老板发送了邮件,发送时间:2025/5/16 10:44:28,邮件内容:下班后开会,王二收到了邮件

EventHandler支持泛型,声明EventHandler为Mail类型,则不需要进行向上向下转型

 public EventHandler<mail> OnSend;//使用EventHandler声明

使用Event,event为委托的实例化对象,event实例化对象需要使用更改代码:

public event EventHandler OnSend;//创建了一个EventHandler对象

更改Main函数:

 static void Main(string[] args)
 {
     Boss boss = new Boss();
     boss.BossName = "张三老板";
     staff staff1 = new staff()
     { 
        StaffName= "张三"
     
      };
     staff staff2 = new staff() { StaffName="李四"};
     staff staff3 = new staff() { StaffName = "王二" };
     boss.OnSend += staff1.ReceiveMaiL;//类的外部,event只能出现在+=/-=左侧
     boss.OnSend += staff2.ReceiveMaiL;
     boss.OnSend += staff3.ReceiveMaiL;
     boss.SendEmail();
 }

打印结果和eventhandler一致.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值