从底层实现角度看,C# 的事件机制是怎么工作的?
考察说明
考察对 C# 事件机制底层实现原理的理解,包括委托、多播委托和事件访问器。
回答思路
- 【回答框架 1】事件机制建立在委托之上,核心是多播委托。一个事件本质上是一个受限的委托字段,通过 add 和 remove 访问器(类似属性)控制外部对事件的订阅和取消订阅。
- 【回答框架 2】编译器在底层将事件定义转换为一个私有的委托类型字段,以及两个方法:add_事件名 和 remove_事件名。这些方法内部调用 Delegate.Combine 和 Delegate.Remove 来维护委托链。
- 【回答框架 3】当事件触发时,实际上调用的是委托字段,这会依次调用委托链上的所有订阅方法。委托链的顺序通常是订阅的顺序,但也可以通过 GetInvocationList 检查。
- 【回答框架 4】多播委托的调用会按顺序执行所有方法,如果某个方法抛出异常,会中断后续方法的执行。此外,如果事件没有订阅者,直接触发会引发 NullReferenceException,因此触发前需要判空。
- 【回答框架 5】事件与委托的区别在于封装性:外部只能通过 add 和 remove 访问器订阅或取消,不能直接赋值或调用委托字段,这保证了事件发布者的安全性。
- 【关键点 1】事件是委托的封装,底层是私有委托字段和 add/remove 访问器。
- 【关键点 2】add 和 remove 内部调用 Delegate.Combine 和 Delegate.Remove。
- 【关键点 3】触发事件前需判空,避免 NullReferenceException。
- 【关键点 4】多播委托按顺序调用,异常会中断后续调用。
- 【易错点 1】不要混淆事件和委托,事件不是变量,不能直接赋值或调用。
- 【易错点 2】多播委托中的异常会中断后续方法,需要自行考虑异常处理。