事件(event)
目录
1.为什么 C# 设计了 event 来限制委托
2.事件如何防止别人随意调用委托
3.用武侠方式解释"报名系统 vs 自由秘籍"的区别
1.为什么需要事件(event)
委托(delegate):一份"能执行招式的方法秘籍".谁拿到它都能执行里面写的招式.
这是不安全的.
为什么不安全
假如你是武林盟主,你定义了一个委托:
public delegate void Notify();
public Notify 武功秘籍;其余人可以这么做
武功秘籍 = null; // 我把你的招式清空了
武功秘籍(); // 我随意发动你的武功
武功秘籍 += 假消息; // 无法武功秘籍(被别人注册一些不想要的方法)后果
- 别人能随时调用你的委托
- 能随时替换掉里面的方法
- 能随意破环逻辑
委托 = 完整暴露、任何人都能乱用的武功秘籍
2.事件(event)的出现
事件 = 安全的委托,只允许别人订阅和退订,不允许别人运行.
比喻:
event是"武林大会报名册".
各大门派可以写上名字(+=),也可以取消(-+).
但谁也不能擅自宣布大会开始(不能调用).
只有盟主(类内部)能启动大会(Invoke).
3.是否使用事件(event)的区别
使用事件(event)前:委托(delegate)暴露在外
public delegate void Notify();
public Notify OnStart;外部可进行受影响的操作
OnStart = null; // 删除你的所有注册者
OnStart(); // 擅自发动事件使用事件(event)后
public delegate void Notify();
public event Notify OnStart;外部只能:
OnStart += 少林寺回应; // 允许
OnStart -= 少林寺会有; // 允许不能进行:
OnStart(); // 错误, 外部不能调用
OnStart = null; // 错误, 外部不能覆盖事件保护了委托不被滥用
4.事件(event) = 被保护的委托(delegate)
事件是: private 委托字段 + public 订阅接口(add/remove) 形成的一个受保护的委托类型成员
public event Kungfu 大会通知;底层逻辑(编译器生成的)
private Kungfu _大会通知;
public void add_大会通知(Kungfu k) { _大会通知 += k; }
public void remove_大会通知(Kungfu k) { _大会通知 -= k; }5.总结
事件永远依赖委托(事件只是委托的保护层)
外部只能订阅和退订(不能触发事件,不能清空事件)
事件用于"通知机制,发布订阅模式"(例如:UI点击事件, 按键事件, 网络消息事件, 游戏角色死亡事件, 系统事件(如文件修改))
事件是 C# 中的一等公民(和属性一样, 是语法糖)