第二部分:C#进阶
第6章:委托与事件
6.2 事件驱动编程
1. 事件的基本概念
事件是C#中基于委托的通信机制,用于实现发布-订阅模型。事件允许对象在特定动作发生时通知其他对象,而无需紧密耦合。
- 发布者(Publisher):触发事件的对象。
- 订阅者(Subscriber):通过事件处理器(Event Handler)响应事件的对象。
2. 定义与使用事件
事件通过event关键字声明,通常遵循以下步骤:
- 定义委托类型:指定事件处理器的签名。
public delegate void EventHandlerDelegate(string message); - 声明事件:基于委托类型。
public event EventHandlerDelegate OnEventTriggered; - 触发事件:通过调用事件(需检查是否为
null)。OnEventTriggered?.Invoke("事件已触发!"); - 订阅事件:其他类通过
+=注册事件处理器。publisher.OnEventTriggered += (msg) => Console.WriteLine($"收到消息:{msg}");
3. 标准事件模式
.NET推荐使用EventHandler委托和EventArgs基类实现标准化事件:
public class CustomEventArgs : EventArgs {
public string Data { get; set; }
}
public class Publisher {
public event EventHandler<CustomEventArgs> StandardEvent;
public void RaiseEvent() {
StandardEvent?.Invoke(this, new CustomEventArgs { Data = "标准事件数据" });
}
}
4. 事件驱动编程的优势
- 松耦合:发布者与订阅者无需直接引用彼此。
- 可扩展性:可动态添加或移除订阅者。
- 响应式设计:适用于UI交互(如按钮点击)、异步通知等场景。
5. 实际示例:按钮点击事件
模拟WPF中的按钮点击事件:
public class Button {
public event EventHandler Click;
public void SimulateClick() {
Click?.Invoke(this, EventArgs.Empty);
}
}
// 订阅事件
Button button = new Button();
button.Click += (sender, e) => Console.WriteLine("按钮被点击!");
button.SimulateClick();
6. 注意事项
- 线程安全:多线程环境下触发事件需确保订阅者线程安全。
- 内存泄漏:长期订阅需通过
-=显式取消,避免阻止垃圾回收。 - 事件命名:建议以
On开头(如OnClick)或过去时态(如Clicked)。
7. 扩展阅读
- 观察者模式:事件是观察者模式的.NET实现。
- Reactive Extensions (Rx.NET):更强大的事件流处理库。
代码示例仓库:可在本书配套GitHub仓库的
Chapter6/EventExamples中找到完整示例。
此内容涵盖了事件的核心概念、实现方式及实际应用,同时提供标准化实践和注意事项,适合读者逐步掌握事件驱动编程。