一.委托和事件:
委托的本质是一个引用数据类型
事件是一个委托的实例化对象(事件的+=和-=),这是委托和事件的本质区别
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一致.