news 2025/12/22 20:46:44

.NET进阶——深入理解委托(4)事件实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
.NET进阶——深入理解委托(4)事件实战

在上一文我们已经大致介绍了关于事件的基础入门,现在我们来一个事件的实战,让大家更加深入的理解事件。这个代码也是观察者模式,如果对这个模式不清楚,可以看我上一个文章:.NET进阶——深入理解委托(3)事件入门

一、前景提要

1.1EventHandler介绍

我们这个代码中的委托使用系统自带的EventHandler委托:

publicdelegatevoidEventHandler(object?sender,EventArgse);

这个委托没有返回值,但需要传递两个参数,一个是object类型的,一个是EventArgs类型的,这两个参数分别是什么意思呢?其实,object类型就是调用者,剩下的EventArgs就是要传递的参数,我这么说可能有点不好理解,接着看下去你就懂了。

1.2 场景背景介绍

你住在 “幸福小区”,物业负责通知业主停水 / 停电等事宜:

  1. 第一步:业主订阅通知张三、李四、王五去物业前台登记:“停水通知一定要告诉我!”(对应代码里的+= 订阅事件);
  2. 第二步:物业准备通知内容物业确定:“明天(2025-12-15)上午 8 点到 12 点,小区停水 4 小时,原因是水管维修”(对应代码里的WaterStopNotice参数);
  3. 第三步:物业挨家挨户通知物业人员上门,对每个登记的业主说:“我是幸福小区物业(sender),通知你:明天 8 点 - 12 点停水 4 小时(e参数)”(对应代码里的Invoke传参);
  4. 第四步:业主响应通知张三:“知道了,我囤点水”;李四:“我提前洗好衣服”;王五:“我提醒爸妈别忘接水”(对应代码里的Buy方法执行不同逻辑)。

二、代码详情

2.1 传递信息类:WaterStopNotice

publicclassWaterStopNotice:EventArgs{publicDateTimeStopTime{get;set;}// 停水开始时间publicintDuration{get;set;}// 停水时长(小时)publicstringReason{get;set;}// 停水原因}

首先,这个类是我们需要传递的信息类,可以看到它是继承自EventArgs类,所以这个类是可以当成EventArgs类传递信息的。

2.2 小区物业类:CommunityProperty

publicclassCommunityProperty{publicstringPropertyName{get;set;}// 物业名称(比如“幸福小区物业”)publicstringPhone{get;set;}// 物业联系电话// 定义“停水通知”事件(对外暴露,业主只能订阅/取消)publiceventEventHandlerWaterStopEvent;// 物业内部的“发通知”方法(对应代码里的PublicShow)publicvoidSendWaterStopNotice(){Console.WriteLine($"【{PropertyName}】开始通知业主停水事宜!");// 准备通知详情(e参数)WaterStopNoticenotice=newWaterStopNotice(){StopTime=newDateTime(2025,12,15,8,0,0),Duration=4,Reason="小区主水管维修"};// 触发事件:挨家挨户通知(传2个参数:物业自己+通知详情)WaterStopEvent.Invoke(this,notice);}}

可以看到在这个类中,我们定义了两个属性,还定义了一个事件:

publiceventEventHandlerWaterStopEvent;

这个事件是把EventHanlder这个委托封装了,我们在1.1讨论了它的两个参数,一个是object类型,一个是EventArgs类型,现在我们把这个委托封装从事件后,这个事件WaterStopEvent也就跟该委托一样,只能接收带有两个参数object? senderEventArgs e,并且没有返回值的方法。

其次,我们还定义了触发方法SendWaterStopNotice,这个方法里我们首先创建了WaterStopNotice的实例对象,用这个实例对象来传递参数,并且我们还触发了事件WaterStopEvent.Invoke(this, notice);,即调用SendWaterStopNotice方法,就可以触发绑定的事件。

触发这个事件时,我们传递了两个参数,一个是this,另一个是刚刚创建的实例noticenotice比较好理解,就是我们创建的用来通知小区业主的信息,但是前面的this是啥呢?

我们都知道this指向的是实例本身,也就是说这里的this传递的是我们后续要将校区业主类CommunityProperty实例化后的那个对象,那么为什么要传递这个实例对象呢?想一想,如果你是小区业主,当有人通知你要停水时,你是不是要确认一下对方是谁,只有确认对方是物业后,你才会选择相信。那么这里也是一样的道理,由于我们的对象中有两个属性,一个是PropertyName物业名字,另一个是物业的电话Phone,所以我们要把这些信息也传递给小区业主,让他们知道发起这个消息的是谁,并且发起消息的人的电话。

2.2 物业类:HouseOwner

publicclassHouseOwner{publicstringName{get;set;}// 业主姓名publicintHouseNumber{get;set;}// 门牌号// 接收通知的方法(对应代码里的Buy)// sender = 物业实例,e = 停水通知详情publicvoidReceiveNotice(object?sender,EventArgse){// 第一步:确认是谁发的通知(把sender转回物业类型)CommunityPropertyproperty=senderasCommunityProperty;if(property==null){Console.WriteLine($"{Name}{HouseNumber}号):收到不明通知,忽略!");return;}// 第二步:获取通知详情(把e转回停水通知类型)WaterStopNoticenotice=easWaterStopNotice;if(notice==null){Console.WriteLine($"{Name}{HouseNumber}号):通知内容无效!");return;}// 第三步:根据通知做准备(不同业主反应不同)Console.WriteLine($"\n【{Name}{HouseNumber}号)】收到通知:");Console.WriteLine($" 通知方:{property.PropertyName}(联系电话:{property.Phone})");Console.WriteLine($" 停水时间:{notice.StopTime:yyyy-MM-dd HH:mm}");Console.WriteLine($" 停水时长:{notice.Duration}小时");Console.WriteLine($" 停水原因:{notice.Reason}");// 不同业主的个性化操作if(Name=="张三")Console.WriteLine($" 张三的操作:立刻去超市买2桶矿泉水!");elseif(Name=="李四")Console.WriteLine($" 李四的操作:现在就把衣服洗了,热水器加满水!");elseif(Name=="王五")Console.WriteLine($" 王五的操作:给爸妈打电话,提醒接水!");}}

在这个类中,我们定义了一个方法:

publicvoidReceiveNotice(object?sender,EventArgse){......}

这个方法接收object? sender, EventArgs e两个参数,没有返回值,这个方法的签名完全符合我们之前说的EventHandle委托的要求,即符合WaterStopEvent的要求。并且我们在方法内部也是通过object sender拿到了小区物业的姓名和电话,通过EventArgs获取了停水通知的各个详细信息。

2.4 执行整个流程

// 1. 创建发布者:幸福小区物业CommunityPropertyproperty=newCommunityProperty(){PropertyName="幸福小区物业",Phone="010-12345678"};// 2. 创建观察者:3个业主HouseOwnerzhangsan=newHouseOwner(){Name="张三",HouseNumber=101};HouseOwnerlisi=newHouseOwner(){Name="李四",HouseNumber=202};HouseOwnerwangwu=newHouseOwner(){Name="王五",HouseNumber=303};// 3. 业主订阅通知(去物业登记)property.WaterStopEvent+=zhangsan.ReceiveNotice;property.WaterStopEvent+=lisi.ReceiveNotice;property.WaterStopEvent+=wangwu.ReceiveNotice;// 4. 物业发通知(触发事件,传递参数)property.SendWaterStopNotice();

这里我们首先创建了一个小区物业的实例,并且声明了他的名称和电话。然后创建了三个业主,声明了每个业主的姓名和房间号。随后,我们让每个业主订阅了物业的通知,即property.WaterStopEvent += zhangsan.ReceiveNotice;,由于WaterStopEvent是一个事件,外部只能订阅(+=)或者取消订阅(-=)。

订阅之后,这些方法会被放到WaterStopEvent事件中,等待调用。而最终,执行SendWaterStopNotice()方法后,这个事件会被调用。

比如当执行了SendWaterStopNotice()方法后,这个代码会触发事件WaterStopEvent.Invoke(this, notice);,将小区物业的实例property和停水消息WaterStopNotice传入事件,由于事件中的第一个方法是张三的,所以执行zhangsan.ReceiveNotice(object? sender, EventArgs e)。剩下两个方法也是以此类推。

执行结果:

【幸福小区物业】开始通知业主停水事宜! 【张三(101号)】收到通知: 通知方:幸福小区物业(联系电话:010-12345678) 停水时间:2025-12-15 08:00 停水时长:4小时 停水原因:小区主水管维修 张三的操作:立刻去超市买2桶矿泉水! 【李四(202号)】收到通知: 通知方:幸福小区物业(联系电话:010-12345678) 停水时间:2025-12-15 08:00 停水时长:4小时 停水原因:小区主水管维修 李四的操作:现在就把衣服洗了,热水器加满水! 【王五(303号)】收到通知: 通知方:幸福小区物业(联系电话:010-12345678) 停水时间:2025-12-15 08:00 停水时长:4小时 停水原因:小区主水管维修 王五的操作:给爸妈打电话,提醒接水!

2.5 总结

生活场景代码里的元素核心作用
幸福小区物业CommunityProperty实例发布者:控制通知时机、传参数
停水通知事件WaterStopEvent事件订阅入口:仅允许 +=/-=
停水详情(时间 / 时长)WaterStopNotice(e 参数)传递具体的通知内容
物业自己(发通知的人)this(sender 参数)告诉观察者 “谁发的通知”
业主登记通知property.WaterStopEvent += 方法订阅:加入通知列表
物业挨家挨户通知WaterStopEvent.Invoke(this, notice)触发事件:传递参数给每个业主
业主按通知做准备ReceiveNotice方法响应:执行个性化逻辑

这个代码也是一个非常典型观察者模式,非常值得大家学习。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/22 21:06:58

Bootstrap 模态框详解

Bootstrap 模态框详解 Bootstrap 模态框是 Bootstrap 框架中一个非常重要的组件,它允许用户在不离开当前页面的情况下,通过一个模态框(Modal)与用户进行交互。本文将详细介绍 Bootstrap 模态框的用法、特性以及注意事项。 一、模态框的基本用法 1.1 创建模态框 要创建一…

作者头像 李华
网站建设 2025/12/22 20:11:34

MinerU终极安全离线部署指南:完全断网环境解决方案

MinerU终极安全离线部署指南:完全断网环境解决方案 【免费下载链接】MinerU A high-quality tool for convert PDF to Markdown and JSON.一站式开源高质量数据提取工具,将PDF转换成Markdown和JSON格式。 项目地址: https://gitcode.com/GitHub_Trendi…

作者头像 李华
网站建设 2025/12/22 21:13:27

练题100天——DAY24:罗马数字转整数+环形链表+大小端判断

今天记录了3道题,难度范围:★★~★★★★。前两道题还是哈希表/哈希集合的使用,第三题是共同体的使用。 今天终于开始继续敲代码了,前几天在复习完成一个大作业,熬到3点,真敲不动,但是现在有空…

作者头像 李华
网站建设 2025/12/22 19:32:27

网站域名:关键的战略资产

网站域名:关键的战略资产 引言 在数字化时代,网站域名已经成为企业、个人乃至政府机构的战略资产。它不仅是网络身份的象征,更是连接用户和内容的重要桥梁。本文将深入探讨网站域名的概念、重要性、选择标准以及管理策略。 一、什么是网站域名? 网站域名是由一串由字母…

作者头像 李华