0

0

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

星降

星降

发布时间:2025-11-25 18:42:06

|

270人浏览过

|

来源于php中文网

原创

委托是方法的类型,用于保存方法引用并实现回调;事件是封装后的委托,支持安全的订阅与通知机制。通过订单系统案例,定义委托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("程序启动了");  // 两个方法都会执行

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

事件是对委托的封装

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

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

免费语音克隆
免费语音克隆

这是一个提供免费语音克隆服务的平台,用户只需上传或录制一段 5 秒以上的清晰语音样本,平台即可生成与用户声音高度一致的 AI 语音克隆。

下载
// 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<t></t> 泛型委托,更标准

比如改写成标准形式:

public event EventHandler<string> OnOrderCreated;

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

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

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

22

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

48

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

93

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

216

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

413

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

143

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

221

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 80.7万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号