C#中的委托(Delegate)和事件(Event)怎么用?一个实战案例让你彻底明白

委托是方法的类型,用于保存方法引用并实现回调;事件是封装后的委托,支持安全的订阅与通知机制。通过订单系统案例,定义委托OrderEventHandler和事件OnOrderCreated,订单服务在创建成功后触发事件,邮件、库存等服务通过订阅实现各自逻辑,实现解耦与扩展。使用?.Invoke避免空引用,推荐EventHandler泛型形式,确保松耦合与可维护性。

c#中的委托(delegate)和事件(event)怎么用?一个实战案例让你彻底明白

委托和事件是C#中非常核心的机制,尤其在处理回调、解耦组件、实现观察者模式时特别有用。很多人学完语法还是不会用,关键在于缺少实战场景。下面通过一个真实小案例,让你彻底搞懂它们怎么配合工作。

什么是委托?

你可以把委托理解为“方法的类型”。它定义了能指向哪些方法——就像变量保存数据,委托保存对方法的引用。

比如:

假设我们有一个日志系统,想让不同模块都能接收日志消息,但又不想写死调用逻辑。这时候就可以用委托来“通知”谁来处理。

// 定义一个委托:能指向返回void,参数为string的方法public delegate void LogHandler(string message);

然后我们可以创建这个委托的实例,指向具体的方法:

public class Logger{    public static void WriteToConsole(string msg)    {        Console.WriteLine("控制台: " + msg);    }    public static void WriteToFile(string msg)    {        File.AppendAllText("log.txt", msg + "n");    }}

使用委托调用:

LogHandler handler = Logger.WriteToConsole;handler += Logger.WriteToFile;  // 多播委托,可以挂多个方法handler("程序启动了");  // 两个方法都会执行

这样,调用方不需要知道具体怎么处理日志,只负责“发出”消息。

事件是对委托的封装

事件本质上是受保护的委托。它防止外部类随意触发或清空回调列表,只允许“注册(+=)”和“注销(-=)”。

继续上面的例子,我们做一个订单系统,当订单创建成功后,通知其他模块做相应操作——比如发邮件、记日志、更新库存等。

// 1. 定义委托public delegate void OrderEventHandler(string orderId);// 2. 创建订单服务类public class OrderService{    // 3. 声明事件    public event OrderEventHandler OnOrderCreated;    public void CreateOrder(string orderId)    {        // 模拟创建订单        Console.WriteLine($"订单 {orderId} 创建成功");        // 4. 触发事件(如果有人订阅)        OnOrderCreated?.Invoke(orderId);    }}

现在,其他模块可以订阅这个事件:

public class EmailService{    public void SendConfirmationEmail(string orderId)    {        Console.WriteLine($"? 发送确认邮件:订单 {orderId}");    }}public class InventoryService{    public void UpdateStock(string orderId)    {        Console.WriteLine($"? 更新库存:订单 {orderId}");    }}

主程序中连接它们:

class Program{    static void Main()    {        var orderService = new OrderService();        var emailService = new EmailService();        var inventoryService = new InventoryService();        // 订阅事件        orderService.OnOrderCreated += emailService.SendConfirmationEmail;        orderService.OnOrderCreated += inventoryService.UpdateStock;        // 创建订单(自动触发事件)        orderService.CreateOrder("ORD-1001");    }}

输出结果:

订单 ORD-1001 创建成功? 发送确认邮件:订单 ORD-1001? 更新库存:订单 ORD-1001

为什么用事件而不是直接调用?

这种设计的好处很明显:

订单服务完全不知道谁在监听,也不依赖 EmailService 或 InventoryService新增功能(比如加个短信通知)只需新类实现方法并订阅事件,原代码不用改测试时可以轻松替换或移除某些行为

这就是典型的松耦合设计,也是事件驱动编程的基础。

常见注意事项

使用事件时注意这些细节:

始终检查事件是否为 null 再调用(OnEvent?.Invoke() 是安全写法)不要从外部类直接触发事件(事件只能在声明它的类内部触发)记得在适当时候取消订阅,避免内存泄漏(尤其是长时间存在的对象)实际项目中常用 EventHandler 泛型委托,更标准

比如改写成标准形式:

public event EventHandler OnOrderCreated;// 触发方式一样OnOrderCreated?.Invoke(this, orderId);

基本上就这些。委托让你能“传递方法”,事件则提供了一种安全、规范的方式来实现“广播-监听”机制。掌握它们,你的代码会更灵活、更易扩展。

以上就是C#中的委托(Delegate)和事件(Event)怎么用?一个实战案例让你彻底明白的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1442196.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月17日 18:50:04
下一篇 2025年12月17日 18:50:32

相关推荐

发表回复

登录后才能评论
关注微信