C#中,什么是委托,什么是事件及它们之间的关系

1. 委托(Delegate)

定义与作用
  • ‌委托‌是类型安全的函数指针,用于封装方法,支持多播(链式调用)。
  • ‌核心能力‌:将方法作为参数传递或异步回调。
使用场景
  1. 回调机制(如异步操作完成通知)。
  2. 实现策略模式(动态替换算法逻辑)。
  3. LINQ查询中的条件筛选(Where(x => x > 6))。
  4. 多播委托(多个方法依次执行)。
示例代码
cs 复制代码
// 定义委托 
public delegate void LogHandler(string message); 
/ 使用委托
 public class Processor 
{ public void RunTask(LogHandler logger) 
{ logger("Task started.");
// ...业务逻辑 logger("Task completed."); 
} 
} // 调用方 
var processor = new Processor(); 
processor.RunTask(message => Console.WriteLine($"[LOG] {message}")); 

2. 事件(Event)

定义与作用
  • ‌事件 ‌是基于委托的语法糖,强制封装性,遵循‌发布-订阅模式‌。
  • ‌核心规则 ‌:只能在声明类内部触发(Invoke),外部仅能+=或-=订阅。
使用场景
  1. GUI事件(按钮点击、鼠标移动)。
  2. 观察者模式(状态变化通知)。
  3. 松耦合系统(组件间通信)。
示例代码
cs 复制代码
// 定义事件
 public class OrderService 
{ 
public event EventHandler<OrderEventArgs> OrderSubmitted; 
public void SubmitOrder(Order order) 
{ 
// ...提交订单逻辑 
OnOrderSubmitted(new OrderEventArgs(order));
 } 
protected virtual void OnOrderSubmitted(OrderEventArgs e) 
{ OrderSubmitted?.Invoke(this, e); } } 
// 订阅事件 var service = new OrderService();
 service.OrderSubmitted += (sender, e) => { 
Console.WriteLine($"Order {e.OrderId} submitted!");
 }; 

3. 委托与事件的关系

‌特性‌ ‌委托‌ ‌事件‌
封装性 可被外部直接调用 只能在声明类内触发
多播 支持 支持
安全性 低(外部可修改委托链) 高(外部仅订阅/取消)
典型用途 灵活的方法传递 系统级通知(如UI交互)

关键点总结

  1. ‌委托是基础 ‌:事件本质是受限的委托,编译器自动生成add/remove方法。
  2. ‌设计原则 ‌:
    • 事件用于‌被动通知‌(如用户操作)。
    • 委托用于‌主动传递逻辑‌(如回调函数)。
  3. ‌代码规范 ‌:事件命名使用动词(如Clicked/DataReceived),委托命名用Handler后缀。

疑问与解决方案

‌Q1:为什么事件比委托更安全? ‌

A1:事件禁止外部直接赋值(=操作符),强制通过+=和-=管理订阅,避免覆盖其他订阅者。

‌Q2:何时选择自定义委托而非Action/Func? ‌

A2:需要明确语义时

(如public delegate void PriceChangedHandler(double oldPrice)优于Action<double>)。

相关推荐
1024奇点4 小时前
【仓颉语言入门 · 第二篇 第 22 课】
开发语言·ide·开源
Warren2Lynch5 小时前
C4 模型详解:利用 Visual Paradigm 可视化软件架构的综合指南
开发语言·uml
Knight_AL6 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
FRing036 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
吃一碗粉只付一碗钱7 小时前
16-SqlSugar多库ConfigId与按实体选连接
sqlserver·c#
by209997 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
砚底藏山河7 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
IT召唤狮7 小时前
开源企业级零信任项目Pangolin,零信任能挡住PHP核弹漏洞吗?
开发语言·开源·php
知已难寻7 小时前
03 · OpenStack的计算管理 Nova
运维·服务器·开发语言·云原生·云计算·openstack·开源软件
Rover Ramble7 小时前
C++ 用互斥锁实现读写锁
开发语言·c++