事件(event)是什么?它和委托是什么关系?
目录
一句话总结:
事件是一种特殊的委托,专用于“发布–订阅”模式,让外部只能订阅/取消订阅,而不能随便触发事件。
换句话说:
- 委托 = “能指向方法的变量”
- 事件(event) = “一个用来广播消息的委托,但加了限制,只允许 += 和 -=”
一、为什么要有事件?直接用委托不行吗?
看这个例子:
public class Button
{
public Action OnClick; // 这是一个委托
}然后外部能这样玩:
button.OnClick = null; // 外部把监听者全部干掉
button.OnClick(); // 外部强制触发事件
button.OnClick = HackMethod; // 全部替换掉这样非常危险。
二、事件解决了这些问题
把上面的代码改成事件:
public class Button
{
public event Action OnClick;
}现在外部 只能做两件事:
button.OnClick += SomeMethod; // 订阅
button.OnClick -= SomeMethod; // 取消订阅外部不能:
button.OnClick(); // ❌ 不能触发
button.OnClick = null; // ❌ 不能替换
button.OnClick = xxx; // ❌ 不能赋值只有 Button 内部才能触发事件:
OnClick?.Invoke();三、事件的完整使用流程
1)定义事件(必须在类内部)
public event Action SomethingHappened;2)订阅事件
obj.SomethingHappened += OnSomething;3)触发事件(只能类内部触发)
SomethingHappened?.Invoke();4)事件响应函数
void OnSomething()
{
Console.WriteLine("事件触发了");
}四、事件为什么经常配合委托?
因为事件其实就是把委托包装了一层访问限制。
你可以把事件理解为:
public delegate void ClickHandler();
private ClickHandler _click;
public event ClickHandler Click
{
add { _click += value; }
remove { _click -= value; }
}也就是说:
事件 = 内部维护一个委托 + 限制外部只能订阅/取消
五、一个简单例子:广播通知
public class Alarm
{
public event Action OnAlarm; // 定义事件
public void Trigger()
{
Console.WriteLine("警报触发!");
OnAlarm?.Invoke(); // 触发
}
}外部:
var alarm = new Alarm();
alarm.OnAlarm += () => Console.WriteLine("听到警报,开始撤离!");
alarm.Trigger();执行结果:
警报触发!
听到警报,开始撤离!六、总结
项目 委托 事件
本质 方法的变量 委托的包装
用途 回调,传方法 发布–订阅
外部能触发吗? ✔ 可以 ❌ 不可以
外部能赋值替换吗? ✔ 可以 ❌ 不可以
外部能 +=/-= 吗? ✔ 可以 ✔ 可以