事件与委托
2009-09-10 11:14 Ivony... 阅读(3545) 评论(11) 编辑 收藏 举报关于事件与委托,说来惭愧一直没能对事件进行深入的研究,一直以来有人问我事件到底是什么。一般都会从用途上加以说明,未曾研究过其实现机制。最近又看到老赵和脑袋两位对事件的应用扩展,下决心彻底把事件的实现研究了一把。
由于MSDN含混不清的误导,很多人(包括我以前)认为,其实事件就是一种受限的委托。但实际上不是,事件与委托的关系好比字段与属性的关系。事件实际上是一种委托属性,只不过这个属性重载的不是赋值运算符,而是+=和-=运算符。
我们知道,对于一个属性而言,对他的赋值和取值运算会被转换为两个方法的调用。
例如obj.A这个属性,则下面的表达式等同于后面的形式:
obj.A = “aaa”; obj.set_A( “aaa” );
string a = obj.A; string a = obj.get_A();
而事件也是一样,假设有一个事件obj.E,则下面的表达式也等同于后面的形式:
obj.E += d; obj.add_E( d )
obj.E -= d; obj.remove_E( d )
与属性一样,事件也可以被继承甚至重写。事件也可以是虚的和抽象的,理论上事件的add和remove也可以是有不同的可见性的。
与属性一样,抽象和虚的事件,其实就是表现为事件的两个方法add和remove是抽象的和虚的。
但是!事件与属性有一个最明显的不同,也就是属性是必须实现的,事件则是不必的。或者说,事件是最早出现的自动属性。
与自动属性一样,事件也会创建一个字段来保存对应的委托实例,而这个字段与事件同名且是私有。在C#中,你可以访问到这个字段,因为它真的就是一个字段。
换言之,当你在C#中写代码时,如果是在类型内部使用类型的事件,其实就是引用到那个自动生成的私有字段。换言之,在类的内部使用事件的时候,你使用的是一个委托字段而不是事件。对这个字段的操作是完全不同于在类的外部使用事件的。
当然,一旦事件写了add和remove访问器,也就不会被自动实现,也就没有这个私有字段了。同样的,因为这个字段是私有的,所以,在类的外部也是访问不到的。
扩展阅读(感谢装配脑袋提供):
1、事件其实是由三个方法add、remove和raise组成的。但C#编译器总是不会生成raise方法。
2、自动事件不同的编译器实现是不同的,例如VB的编译器生成的私有字段是(事件名)Event。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!