目录

事件(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# 中的一等公民(和属性一样, 是语法糖)