type
status
date
slug
summary
tags
category
icon
password
Property
Aug 14, 2023 11:53 AM

事件的声明

事件的声明
  • 完整声明
  • 简略声明(字段式声明,field-like)
有了委托字段/属性,为什么还需要事件
  • 为了程序的逻辑更加“有道理”、更加安全,谨防“借刀杀人”
所以事件的本质是委托字段的一个包装器
  • 这个包装器对委托字段的访问起限制作用,相当于一个“蒙版”
  • 封装(encapsulation)的一个重要功能就是隐藏
  • 事件对外界隐藏了委托实例的大部分功能,仅暴露添加/移除事件处理器的功能
  • 添加/移除事件处理器的时候可以直接使用方法名,这是委托实例所不具备的功能
用于声明事件的委托类型的命名约定
  • 用于声明Foo事件的委托,一般命名为FooEventHandler(除非是一个非常通用的事件约束)
  • FooEventHandler委托的参数一般有2个(由Win32 API演化而来,历史悠久)
    • 第一个是object类型,名字为sender,实际上就是事件的拥有者、事件的source
    • 第二个是EventArgs类的派生类,类名一般为FooEventArgs,参数名为e。也就是前面讲过的事件参数
    • 虽然没有官方的说法,但我们可以把委托的参数列表看做是事件发生后给事件响应者的“事件消息”
  • 触发Foo事件的方法一般命名为OnFoo,即“因何引发”、“事出有因”
    • 访问级别为protected,不能为public,不然又成了可以“借刀杀人”了
事件的命名约定
  • 常有时态的动词或者动词短语
  • 事件拥有者“正在做”什么事情,用进行时;事件拥有者“做完了”什么事情,用完成时
事件成员不论从表层约束还是底层实现,都是依赖委托的。
事件声明完整格式
简略声明
"借刀杀人"的案例
public的委托字段有可能在外部被其他调用、误用,所以要用这种形式:public event OrderEventHandler Order;
使用内部的EventHandler
一定要判断,方法是否存在
onEvent专门触发事件

事件与委托的关系

事件真的是“以特殊方式声明的委托字段/实例”吗?
  • 不是!只是声明的时候“看起来像”(对比委托字与事件的简化声明,field-like)
  • 事件声明的时候使用了委托类型,简化声明造成事件看上去像一个委托的字段(实例),而event关键字则更像是一个修饰符–这就是错觉的来源之一
  • 订阅事件的时候+=操作符后面可以是一个委托实例,这与委托实例的复制方法语法相同,这也让时间看起来像是一个委托字段–这是错觉的又一来源
  • 重申:事件的本质是加装在委托字段上的一个“蒙版”(mask),是个起掩蔽作用的包装器。这个用于阻挡非法操作额“蒙版”绝不是委托字段本身
为什么要使用委托类型来声明事件
  • 站在source的角度来看,是为了表明source能对外传递哪些消息
  • 站在subscriber的角度来看,它是一种约定,是为了约束能够使用什么样的签名的方法来处理(响应)事件
  • 委托类型的实例将用于存储(引用)事件处理器
对比事件与属性
  • 属性不是字段–很多时候属性是字段的包装器,这个包装器用来保护字段不被滥用
  • 时间不是委托字段—他是委托字段的包装器,这个包装器用来保护委托字段不被滥用
  • 包装器永远都不可能是被包装的东西
C#知识学习—17 事件详解(2)C#知识学习—14 方法参数进阶,扩展方法
  • Waline
Kitety
Kitety
独特为佳
公告
我曾经七次鄙视自己的灵魂
--卡里·纪伯伦
第一次,当它本可进取时,却故作谦卑;
第二次,当它在空虚时,用爱欲来填充;
第三次,在困难和容易之间,它选择了容易;
第四次,它犯了错,却借由别人也会犯错来宽慰自己;
第五次,它自由软弱,却把它认为是生命的坚韧;
第六次,当它鄙夷一张丑恶的嘴脸时,却不知那正是自己面具中的一副;
第七次,它侧身于生活的污泥中,虽不甘心,却又畏首畏尾。
 
最新评论
Loading...