优秀的编程知识分享平台

网站首页 > 技术文章 正文

C# 事件(Event)是基于委托(Delegate)的发布

nanyue 2025-05-08 03:59:07 技术文章 3 ℃

一、事件的核心组成

  1. 发布者(Publisher)
    负责声明事件、触发事件的对象。事件触发时通过委托通知订阅者。
public class Button { 
public event EventHandler Click; // 事件声明 
protected virtual void OnClick() 
{ 
		   Click?.Invoke(this, EventArgs.Empty); // 触发事件 
}
  1. 订阅者(Subscriber)
    通过事件处理方法响应事件的对象,需与事件委托签名匹配。
public class UserInterface { 
public void HandleButtonClick(object sender, EventArgs e) 
{ 
    Console.WriteLine("按钮被点击!"); 
} 
  1. 事件委托(Event Delegate)
    定义事件的参数和返回值类型。常用 EventHandler 或自定义委托。

二、事件声明与使用流程

  1. 声明委托类型(若未使用标准模式)
public delegate void LogEventHandler(string message);
  1. 定义事件
public class Logger { 
    public event LogEventHandler Logged; // 事件基于委托 
}
  1. 触发事件
    通过方法封装触发逻辑,通常以 On 开头:
public void Log(string message)
 { 
Logged?.Invoke(message); // 空条件操作符避免空引用 
}
  1. 订阅与取消订阅
    使用 +=-= 操作符管理订阅关系26
Logger logger = new Logger(); 
logger.Logged += message => Console.WriteLine(message); // Lambda表达式订阅 
logger.Logged -= SomeMethod; // 取消订阅

三、标准事件模式

使用 EventHandler<TEventArgs> 和自定义事件参数类:

public class TemperatureChangedEventArgs : EventArgs {
    public double NewTemperature { get; set; }
}

public class Thermostat {
    public event EventHandler<TemperatureChangedEventArgs> TemperatureChanged;
    protected virtual void OnTemperatureChanged(double temp) {
        TemperatureChanged?.Invoke(this, new TemperatureChangedEventArgs { NewTemperature = temp });
    }
}

优势:统一参数结构,兼容性强。


四、事件与委托的区别

特性

事件(Event)

委托(Delegate)

封装性

外部仅能订阅/取消订阅

可被外部直接调用或覆盖

多播支持

是(支持多个订阅者)

安全性

防止外部触发,保护逻辑完整性

无此限制


五、典型应用场景

  1. 用户界面交互(如按钮点击、键盘输入)。
  2. 异步操作通知(如文件下载完成、网络请求响应)。
  3. 插件系统扩展(通过事件暴露扩展点)。

六、注意事项

  1. 空事件检查:触发前需判断事件是否为 null(可用 ?.Invoke() 简化)。
  2. 资源释放:订阅长期存在的发布者可能导致内存泄漏,需及时取消订阅。
  3. 线程安全:跨线程触发事件时需通过 Invoke 同步到主线程。

Tags:

最近发表
标签列表