首页/新闻资讯/正文详情

C# 委托与事件

发布时间:2026/11/5 3:48:17 来源:云帆数科 栏目:资讯中心
C# 委托与事件
在.NET Core的开发体系中委托是构建灵活、低耦合应用架构的核心基础它打破了传统方法调用的强绑定关系让开发者可以将方法作为一等对象进行传递和管理。从基础的函数指针封装到事件机制、观察者模式的落地实现委托贯穿了.NET Core中绝大多数异步通知、回调解耦的场景。1.委托是类型安全的函数指针委托本质上是一种继承自System.MulticastDelegate的特殊类类型它定义了方法的签名规范是.NET中实现类型安全回调的核心载体。和不安全的函数指针不同委托会严格校验目标方法的参数类型、数量和返回值只有完全匹配签名的方法才能被委托实例引用从根源上避免了非法内存调用的风险。在.NET Core中声明一个自定义委托只需要明确它的参数列表和返回值即可// 定义一个用于计算的委托接收两个int参数返回int结果 public delegate int Calculate(int x, int y);使用时可以直接将匹配签名的方法赋值给委托实例后续就能像调用普通方法一样执行委托指向的逻辑public class MathOperations { public int Add(int a, int b) a b; } // 实例化委托绑定Add方法 Calculate calc new MathOperations().Add; int result calc(5, 3); // 执行后得到结果8为了避免开发者重复定义通用委托.NET Core内置了三种常用泛型委托覆盖大多数日常开发场景Action系列所有无返回值的方法委托支持0到16个输入参数FuncTResult系列所有带返回值的方法委托最后一个泛型参数指定返回值类型PredicateT专门用于返回布尔值的委托常用来实现集合元素的筛选逻辑2.委托实现模块解耦传统开发中如果两个模块需要传递执行逻辑往往需要通过硬编码依赖或者大量接口定义来实现模块之间的耦合度极高一旦内部逻辑调整就可能引发连锁修改。委托的出现彻底解决了这个问题它让调用方和执行方只需要约定统一的方法签名不需要互相感知对方的具体实现完全实现了逻辑的解耦。举一个典型的场景数据校验模块和业务处理模块分离。校验模块不需要知道后续要执行什么业务逻辑只需要对外暴露一个委托参数任何传入匹配签名方法的调用者都能在数据校验通过后自动执行对应逻辑public class DataValidator { // 传入一个委托作为校验通过后的回调 public void CheckData(int inputData, Actionint onValidSuccess) { if (inputData 0) { // 校验通过执行传入的回调逻辑 onValidSuccess.Invoke(inputData); } } }后续业务扩展时不管是新增日志记录逻辑、数据库写入逻辑还是缓存更新逻辑都不需要修改DataValidator的内部代码只需要传入不同的委托方法即可两个模块之间完全没有硬编码依赖极大提升了代码的可维护性。3.基于委托的灵活逻辑封装委托可以将零散的可变逻辑封装成独立的单元和固定不变的主流程代码完全分离开发者可以在不修改主框架代码的前提下灵活替换不同的业务实现这也是策略模式在.NET中最轻量化的落地方式。比如实现一个通用的集合遍历处理方法遍历的主流程是固定的但每个元素的处理逻辑可以通过委托动态传入public static void ProcessCollectionT(ListT source, ActionT processItem) { foreach (var item in source) { processItem(item); } }后续使用时既可以传入打印元素的逻辑也可以传入元素转换、统计筛选的逻辑同一个主流程可以适配完全不同的业务场景不需要为每一种处理逻辑都重写一遍遍历代码大幅减少了重复代码的编写。4. 多播委托是管理多个执行链所有委托都天然继承自MulticastDelegate这意味着一个委托实例可以同时绑定多个方法形成一条完整的调用链这就是多播委托的核心能力。开发者可以使用操作符向委托实例中添加多个方法使用-操作符移除已绑定的方法调用委托时会按照方法添加的顺序依次执行所有绑定的逻辑。Action multiAction () Console.WriteLine(执行第一个方法); multiAction () Console.WriteLine(执行第二个方法); multiAction () Console.WriteLine(执行第三个方法); multiAction.Invoke(); // 输出顺序 // 执行第一个方法 // 执行第二个方法 // 执行第三个方法使用多播委托时需要注意两个关键特性如果委托带有返回值调用多播委托后只会返回最后一个执行方法的返回值前面所有方法的返回结果都会被忽略移除委托方法时必须传入完全一致的方法引用才能成功移除匿名方法由于每次生成的实例不同几乎无法通过-操作符成功解绑5. 委托与事件是封装安全的通知机制直接将委托作为类的公开成员对外暴露会存在安全隐患外部代码可以随意清空委托的所有绑定方法甚至直接替换整个委托实例破坏类内部的通知逻辑。为了解决这个问题C#提供了event关键字它本质上是对委托的一层封装只允许外部使用和-进行订阅和取消订阅操作完全禁止外部直接赋值和调用委托从语法层面保证了通知机制的安全性。.NET Core中推荐使用标准的事件定义模式基于内置的EventHandler和EventHandlerTEventArgs来声明事件// 自定义事件参数传递事件相关数据 public class ThresholdReachedEventArgs : EventArgs { public int CurrentValue { get; set; } public int Threshold { get; set; } } public class Counter { // 声明事件 public event EventHandlerThresholdReachedEventArgs ThresholdReached; // 受保护的虚方法用于触发事件允许派生类重写逻辑 protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) { // 空合并运算符避免订阅者为空时触发空异常 ThresholdReached?.Invoke(this, e); } public void CountToThreshold(int threshold) { for (int i 0; i threshold; i) { if (i threshold) { OnThresholdReached(new ThresholdReachedEventArgs { CurrentValue i, Threshold threshold }); } } } }.NET Core 及之后的版本还放宽了事件参数的约束不再要求自定义的TEventArgs必须继承自System.EventArgs你可以直接使用结构体作为事件参数进一步提升值类型场景下的性能表现。6. 基于委托实现观察者模式观察者模式的核心是实现发布者和多个订阅者之间的推送通知机制传统的观察者模式需要定义大量接口、维护订阅者列表、编写循环通知的逻辑而借助多播委托你可以用非常少的代码实现完整的观察者能力。比如实现一个猫叫触发所有动物做出反应的场景不需要定义任何订阅者接口直接用多播委托维护所有订阅者的响应逻辑public class CatPublisher { // 用多播委托维护所有订阅者的响应方法 public Action OnCatMeow; public void Meow() { Console.WriteLine(猫叫了一声); // 依次通知所有订阅者 OnCatMeow?.Invoke(); } } // 订阅者逻辑 var cat new CatPublisher(); cat.OnCatMeow () Console.WriteLine(狗开始汪汪叫); cat.OnCatMeow () Console.WriteLine(老鼠立刻躲起来); cat.OnCatMeow () Console.WriteLine(鸭子嘎嘎嘎跑开); cat.Meow();这种基于委托实现的观察者模式比传统接口实现的版本更加轻量化不需要维护复杂的订阅者集合所有的方法管理都由委托的调用链自动完成。如果需要更标准的.NET官方观察者实现还可以使用IObservableT和IObserverT接口适配更复杂的异步推送场景。7. 委托和事件的核心区别与选型委托和事件的使用场景二者的核心差异本质上是访问控制和职责边界的不同委托是一个完整的类类型它可以被任意赋值、调用、作为方法参数传递适合用来做回调、策略封装、方法传递等场景事件是委托的封装成员它只允许外部订阅和取消订阅不支持直接赋值和外部触发专门用于实现对象状态变更的通知机制在实际开发中如果你需要向外暴露一个状态变化的通知点优先使用事件它能保证通知机制的安全性避免外部代码意外破坏内部逻辑如果你需要传递一段可变的逻辑、封装不同的执行策略直接使用委托即可不需要额外包装成事件。从底层运行逻辑来看事件本质上就是在类内部封装了一个私有委托字段只对外暴露add和remove两个访问器所有事件的能力都建立在委托的基础之上二者共同构成了.NET Core中整个回调和通知体系的基石。

相关推荐

Qt 对话框、QLineEdit 与布局管理实战详解
Qt 对话框、QLineEdit 与布局管理实战详解

目录 引言 一、模态对话框:accept /reject 消息机制 1. 项目搭建 2. 主界面 ↔ 登录界面互相切换 二、QT内置标准对话框 2.1 QColorDialog 颜色对话框 2.2 QFileDialog 文件选择对话框 2.3 QInputDialog 输入对话框(4 种类型) 2.4 Q… · 2026/11/5 3:48:17

alertmanger 告警rule文件配置(二)
alertmanger 告警rule文件配置(二)

#样例groups: - name: dev-node-exporterrules:- alert: dev-node-exporter-down #告警名称expr: up{job"node-exporter"} 0 # PromQL表达式for: 5m #最大持续时间labels: serverity: 100 # 告警程度 # team: test #team分组 Alertmanager对应值分组告警an… · 2026/11/5 3:48:17

Linux 学习笔记(五十四):内网穿透实战——用 frp 让外网访问你的私人电脑
Linux 学习笔记(五十四):内网穿透实战——用 frp 让外网访问你的私人电脑

📌 核心结论(TL;DR):内网穿透背景:由于 NAT 技术的存在,外部网络无法主动连接内网的私有 IP。核心思路:利用一台拥有公网 IP 的服务器作为中转站。frp 架构:由运行在公网的 frps 和运… · 2026/11/5 3:47:17

零基础3个月速成网络安全工程师实战指南
零基础3个月速成网络安全工程师实战指南

1. 项目概述作为一名在网络安全领域摸爬滚打多年的从业者,我经常被问到同一个问题:"零基础如何快速入门网络安全?"今天我就把自己当年用3个月时间从完全不懂到能够独立完成基础渗透测试的学习路径完整分享出来。这份清单之所以被称… · 2026/11/5 4:40:54

AI驱动的数据采集:Bright Data MCP与Trae实践指南
AI驱动的数据采集:Bright Data MCP与Trae实践指南

1. 项目概述:AI时代的数据采集新范式最近半年我一直在探索如何将AI能力融入传统数据采集工作流。作为一名长期从事网络数据采集的开发者,我深刻感受到大模型技术对爬虫领域的颠覆性影响。过去我们需要花费大量时间处理反爬机制、解析网页结构、维护代理I… · 2026/11/5 4:40:54

Java C++算法题解leetcode801使序列递增的最小交换次数
Java C++算法题解leetcode801使序列递增的最小交换次数

前言 LeetCode 801 的题意是:给定两个长度相同的整数数组 nums1 和 nums2,每次操作可以交换某个下标 i 上的两个元素,问最少交换多少次,能使两个数组都严格递增。题目保证答案存在。 这道题最容易掉进的坑是贪心:看到某… · 2026/11/5 4:40:54

基于ECharts的实时天气可视化开发实践
基于ECharts的实时天气可视化开发实践

1. 项目背景与核心价值去年夏天帮朋友改造民宿时,发现他们前台用的天气显示还是老式LED屏,不仅信息单一,遇到极端天气也缺乏预警提示。于是用周末时间做了这个网页版天气可视化工具,现在已经成为他们日常运营的标配。相比传统方案… · 2026/11/5 4:40:54

MySQL 把 GROUP_CONCAT 结果当 IN 条件失效的原因与改写
MySQL 把 GROUP_CONCAT 结果当 IN 条件失效的原因与改写

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 4:40:54

TED精读如何训练高阶英语思维与认知能力
TED精读如何训练高阶英语思维与认知能力

1. 项目概述:这不是一节普通英语课,而是一次认知升级的实操训练“跟TED演讲学英文:How AI can save our humanity by Kai-Fu Lee”——这个标题乍看是语言学习类内容,但真正懂行的人一眼就能看出,它根本不是在教“how … · 2026/11/5 4:39:54

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38

多智能体协作系统架构设计与实践优化
多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39

大模型系统性入门实战指南:从原理到部署微调的全链路路线
大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39

鸿蒙文件系统沙箱机制解析与开发实践
鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码