0

0

C# 责任链模式实现方法 C#如何构建处理请求的链条

星降

星降

发布时间:2026-02-11 08:29:02

|

372人浏览过

|

来源于php中文网

原创

应使用抽象类Handler而非接口,因其可提供SetNext和默认委托调用逻辑,避免重复代码与空引用风险;关键在于持有_next引用、Handle返回bool控制链路、SetNext支持链式调用。

c# 责任链模式实现方法 c#如何构建处理请求的链条

如何用抽象类定义统一的 Handler 接口

责任链的核心是让每个处理器能处理请求,也能把请求传给下一个。C# 中最稳妥的方式是定义一个抽象基类 Handler,而不是接口——因为接口无法提供默认的 SetNext 和委托调用逻辑,容易导致重复代码或空指针风险。

关键点在于: - Handler 必须持有对下一个 Handler 的引用(可为空) - 处理方法(如 Handle)应返回 boolobject 表示是否终结链条,避免隐式跳过后续节点 - SetNext 应返回 this,支持链式调用(如 h1.SetNext(h2).SetNext(h3)

public abstract class Handler
{
    protected Handler? _next;
    public Handler SetNext(Handler next) { _next = next; return this; }
    public virtual bool Handle(string request)
    {
        return _next?.Handle(request) == true;
    }
}

具体 Handler 如何判断是否处理并决定是否继续

每个子类重写 Handle 时,必须显式判断当前请求是否属于自己的职责范围;若不处理,不能直接 return false,而应调用 _next?.Handle(...),否则链条会意外中断。

常见错误: - 在条件不满足时写 return false;,导致后续 Handler 完全没机会执行 - 忘记检查 _next 是否为 null,引发 NullReferenceException - 把业务逻辑和“是否继续”耦合太紧,比如用 if (x) { ... } else { return _next?.Handle(...) },但漏掉对 _next 的空值保护

推荐写法: - 用 if (CanHandle(request)) { ... return true; } 明确职责边界 - 结尾统一用 return _next?.Handle(request) == true;,既安全又语义清晰 - 若需透传结果(如修改后的 request),可改用 string? Handle(string request),返回 null 表示终止

如何组装链条并避免循环引用或遗漏

手动串联时最容易出错的是顺序颠倒、漏设 SetNext,或无意中形成环(比如 a.SetNext(b); b.SetNext(a);)。生产环境建议用工厂或配置驱动构建。

Komo Search
Komo Search

Komo Search 是一个生成式AI驱动的搜索引擎

下载

实操建议: - 链条起点必须是非 null 的第一个 Handler,且终点 Handler 的 _next 必须为 null - 单元测试里加断言:遍历链条长度 ≤ 预期数,且无重复实例(可用 Object.ReferenceEquals 检查) - 如果 Handler 有状态(如计数器、缓存),注意多线程下是否线程安全;无状态 Handler 可复用,有状态的建议每次新建 - 不要用静态字段保存链条,会导致不同请求互相干扰

为什么不用委托链或 LINQ Aggregate 实现

有人尝试用 Func 数组 + Aggregate 模拟责任链,看起来简洁,但实际问题不少:

硬伤包括: - 无法在中途修改请求内容(委托签名固定) - 调试困难:堆栈里全是 Aggregate 内部帧,看不出哪个 Handler 出了问题 - 无法动态插入/跳过某个 Handler(比如根据配置开关日志 Handler) - 每次调用都重新遍历整个数组,无短路优化,性能不如原生引用跳转

委托适合简单过滤场景(如中间件管道),但真正需要“职责分离 + 动态协作 + 可调试”的业务逻辑链,还是老老实实用类继承更可控。

责任链不是越“链”越好,关键是每个 HandlerCanHandle 判断逻辑是否足够轻量,以及链条长度是否在可预期范围内——超过 5–6 层时,就得考虑是不是职责划分过细,或者该用策略模式+路由表替代了。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

180

2024.05.11

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

222

2025.12.18

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

688

2023.08.02

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

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

243

2023.09.22

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

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

664

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

803

2023.08.22

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

803

2023.08.22

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

803

2023.08.22

包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法
包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法

本专题汇总了包子漫画官网和网页版入口,提供最新章节抢先看方法、正版免费阅读指南,以及稳定访问方式,帮助用户快速直达包子漫画页面,无广告畅享全集漫画内容。

50

2026.02.10

热门下载

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

精品课程

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

共94课时 | 9.1万人学习

C 教程
C 教程

共75课时 | 4.6万人学习

C++教程
C++教程

共115课时 | 17.1万人学习

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

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