自定义事件的完整声明
前言:
编程规范:声明的委托类型用EventHandler作为后缀
编程规范:用于传递事件数据的类名,用EnventArgs作为后缀
委托、事件拥有者(customer)、事件数据传递类要配合在一起使用,所以他们的访问基本必须的一样的。
step1.声明事件封装的委托类型
step2.在事件拥有者中声明事件
建一个委托变量来装事件处理器
事件名与其封装的委托类名一致
通过重载操作符+=、-+,设置好事件的订阅与退订操作符
用value指代要添加或移除的方法
step3.在事件拥有者中调用委托字段
(事件类似属性,委托类似字段?都是一种封装)
step4.定义一些作为事件处理器的方法
step5.在外部用事件处理器方法订阅事件
所以事件的本质是对委托的封装!
事件对外隐藏了委托实例的大部分功能,仅暴露添加、移除事件处理器的功能
添加、移除事件处理器是可直接用方法名,这是委托实例不具备的功能
自定义事件的简略声明
补充:事件逻辑中使用委托调用方法的原因
之前的完整声明中,最后调用方法的用的委托
因为:
事件只能放在+=、-=操作符左边
作为封装的委托,事件只对外暴露了这两个接口
事件的简略声明
和完整声明一样,首先要有一个委托类(类型)
但完整声明中在此定义了一个委托类型的实例变量(字段),之后逻辑中使用委托调用方法
而这样的简略声明,缺失了定义委托实例变量(字段)的过程
之后迫不得已,使用了语法糖,让简略声明的事件,能够直接调用方法
产生了语法的前后不一致,还容易将事件误会为委托字段,可见C#也并非尽善尽美
与其他语法糖一样,事件的简略声明编译后和完整声明是一样 的,只是隐藏了委托字段
事件的两大意义:
1.封装委托,保证安全性,防止借刀杀人,只对外暴露+=和-=,防止委托字段被非法篡改
2.衔接现实逻辑,使程序逻辑清晰易读
通用模板委托EventHandler
对于事件,.Net平台有准备好的EventHandler委托,作为一个通用模板
使用它就可以省去step1的委托类型声明
第一个参数sender:传递对象(就是事件的拥有者、事件的源头)
第二个参数e:EventArgs类型,用于传递事件的数据(事件消息)
所以传递事件数据的类,都继承自EventArgs类
对于事件处理器方法,EventHandler模板委托将对象和数据通过传递进来之后,需要进行类型转换
将通用类型(object、EventArgs)的参数,转换为对应的专用类型(Costomer、OrderEventArgs)
(感觉有点泛型的思想?)
99%的情况下,使用事件都不自定义委托类型,都是直接用这个模板
命名规范
用于声明Foo事件的委托,一般命名为FooEventHandler
传递事件数据的类,一般命名为“事件名EventArgs”,继承自EventArgs
触发事件的方法一般命名为OnFoo,其访问级别一般为protected,事件只能由事件的拥有者自己访问
事件的命名一般是一个瞬时性动词,或时态需要正确,可用时态标记事件在事情发生前还是发生后
面向对象原则:一个方法只干一件事
为什么要用委托声明事件
对比事件与属性
都是保护性的封装,事件封装委托,属性封装字段(变量)
包装器永远不可能是被包装的物品本身
分类:
刘铁猛C#教程学习笔记
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具