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

Humanizer ITruncator 接口深度解析:.NET 字符串截断的四种内置策略与自定义扩展机制

发布时间:2026/9/25 2:45:30 来源:云帆数科 栏目:资讯中心
Humanizer ITruncator 接口深度解析:.NET 字符串截断的四种内置策略与自定义扩展机制
开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载Humanizer 库中的ITruncator接口是字符串截断功能的统一抽象它把截断到什么长度、用什么标记、从哪一侧截断这三个变量封装进单一方法签名中配合TruncateExtensions扩展方法和五个内置截断器覆盖从硬截断到按词保留的常见展示场景。读完本文你将能够准确选用 Humanizer 的截断 API、理解五种内置ITruncator实现各自的算法边界并知道如何注入自定义截断器扩展这一接口。一、ITruncator 接口定义ITruncator是一个只含单个方法的接口声明位于 ITruncator.cs其公开成员只有一个Truncate方法public interface ITruncator { string Truncate(string value, int length, string truncationString, TruncateFrom truncateFrom TruncateFrom.Right); }接口文档XML 注释对四个参数与返回值的定义如下参数类型说明valueSystem.String要被截断的字符串lengthSystem.Int32截断目标长度结果的最大长度含截断标记truncationStringSystem.String截断时使用的标记字符串如…、...truncateFromTruncateFrom枚举值决定从字符串的哪一侧截断默认TruncateFrom.Right返回值System.String截断后的字符串。从源码结构看接口方法还标注了[return: NotNullIfNotNull(nameof(value))]见 ITruncator.cs 第 16 行这为 nullable 引用类型分析提供了语义约束入参为null时所有实现都必须返回null非null输入则保证返回非null字符串。TruncateFrom 枚举TruncateFrom定义于 TruncateFrom.cs只有两个取值public enum TruncateFrom { Left, // 从字符串的左侧开头截掉字符 Right // 从字符串的右侧结尾截掉字符 }方向语义在所有截断器中保持一致Right默认保留字符串前部、截去尾部并追加标记Left截去前部、标记置于结果最前面。二、标准调用入口TruncateExtensions 扩展方法接口本身不直接面向用户——日常使用通过 TruncateExtensions.cs 提供的四组Truncate扩展方法完成它们是ITruncator的适配层// 重载 1固定长度截断默认标记 …默认方向 Right string.Truncate(int length) // 重载 2指定截断器实例 string.Truncate(int length, ITruncator truncator, TruncateFrom from TruncateFrom.Right) // 重载 3指定自定义截断标记使用固定长度截断器 string.Truncate(int length, string truncationString, TruncateFrom from TruncateFrom.Right) // 重载 4最灵活标记 截断器 方向全部可定制 string.Truncate(int length, string truncationString, ITruncator truncator, TruncateFrom from TruncateFrom.Right)源码中的 XML 示例给出了可直接复制的行为预期TruncateExtensions.cs 第 21–27 行This is a long string.Truncate(10) This is a… Short.Truncate(10) Short null.Truncate(10) null This is a long string.Truncate(10, Truncator.FixedLength, TruncateFrom.Left) …ng string This is a long string.Truncate(10, ...) This is... This is a long string.Truncate(15, --) This is a lo-- This is a long string.Truncate(10, ..., TruncateFrom.Left) ...string从实现看重载 4 是唯一真正的入口它先通过ArgumentNullException.ThrowIfNull(truncator)拒绝null截断器null输入直接透传null否则委托给truncator.Truncate(input, length, truncationString, from)见 TruncateExtensions.cs 第 117–127 行。其余重载只是以…或Truncator.FixedLength为默认值转发到该重载。三、Truncator 静态类与五个内置截断器Truncator.cs 是一个静态工厂类以只读属性暴露五个单例截断器实例构成ITruncator的内置实现全集public static class Truncator { public static ITruncator FixedLength { get; } // new FixedLengthTruncator() public static ITruncator FixedNumberOfCharacters { get; } // new FixedNumberOfCharactersTruncator() public static ITruncator FixedNumberOfWords { get; } // new FixedNumberOfWordsTruncator() public static ITruncator DynamicLengthAndPreserveWords { get; } // new DynamicLengthAndPreserveWordsTruncator() public static ITruncator DynamicNumberOfCharactersAndPreserveWords { get; } // new DynamicNumberOfCharactersAndPreserveWordsTruncator() }以下逐一剖析每个实现的核心算法。3.1 FixedLengthTruncator按字符硬截断FixedLengthTruncator.cs 是最直白的策略——length就是最终字符串的总长度null/ 空串 / 长度已不超限 → 原样返回若truncationString为null或其长度超过length退化为纯子串Right取value[..length]Left取value[^length..]否则结果总长恰好为lengthRight方向为前(length - 标记长)字符 标记Left方向为标记 尾部(length - 标记长)字符。例如Text longer than truncate length.Truncate(10, ...)得到Text lo...10 字符。这一标记超长则丢弃标记的退化逻辑在测试用例中得到了印证输入长度 2、标记...时输出Te而非抛错见 TruncatorTests.cs 第 86 行用例。3.2 FixedNumberOfCharactersTruncator只统计字母与数字FixedNumberOfCharactersTruncator.cs 的关键差异在于length只计算字母和数字char.IsLetterOrDigit空格、标点不占额度先以 O(1) 中断式循环统计字母数字总数未超限直接返回原文Right方向正序扫描当已处理的字母数字数 标记长度 length时在该位置切断并拼上标记Left方向倒序扫描同样满足额度相等后在前方插入标记。例如Text with more characters than truncate length.Truncate(10, Truncator.FixedNumberOfCharacters)输出Text with m…——虽然结果含空格但额度只花在 10 个字母上。3.3 FixedNumberOfWordsTruncator按词计数截断FixedNumberOfWordsTruncator.cs 把length解释为词数先用状态机wasWhiteSpace标志无数组分配统计全串词数numberOfWords length时原样返回TruncateFromRight正序扫描第length个词结束于空白处时返回前缀 标记TruncateFromLeft倒序扫描保留尾部length个词标记置于最前并对结果TrimEnd。测试中特别验证了换行、回车、制表符均可作为词分隔符Words are\nsplit\rby\twhitespace.Truncate(4, Truncator.FixedNumberOfWords)得到Words are\nsplit\rby…见 TruncatorTests.cs 第 49 行用例。3.4 DynamicLengthAndPreserveWordsTruncator定长预算内保留完整词DynamicLengthAndPreserveWordsTruncator.cs 解决硬截断把单词切断的体验问题——若截断点落在词中间则整个丢弃该词把预算让给完整词右截断先算effectiveLength length - 标记长若该位置不是空白回退到LastIndexOf( , effectiveLength)处若回退后前缀为空只返回标记…左截断从尾部向前找空白边界保留的尾段若超过allowedContentLength即length - 标记长或为空同样只返回标记。典型行为测试第 05 组见 TruncatorTests.cs 第 53–64 行Text longer than truncate length.Truncate(10, Truncator.DynamicLengthAndPreserveWords) Text… // longer 放不下整词直接截到 Text …starting word longer than truncate length….Truncate(4, …) … // 没有完整词能放进 4 字符预算只剩标记3.5 DynamicNumberOfCharactersAndPreserveWordsTruncator字母数字预算 保词DynamicNumberOfCharactersAndPreserveWordTruncator.cs 是 3.2 与 3.4 的组合length只计入字母数字空格不占额度同时绝不把词切断。从源码结构看它是五个实现中唯一声明为public class的截断器其余四个均为内部class这意味着它被设计为可直接new并在外部继承/复用的开放实现。其算法要点正向/逆向扫描同时维护alphaCount字母数字计数与最近的空白位置lastSpace/nextSpace当alphaCount 标记长 totalLength时记下候选截断点若候选点落在词中则回退/前进到最近空白多个分支的最终校验若前缀字母数 标记长仍超预算则只返回标记。测试第 06 组展示了与硬截断的差异见 TruncatorTests.cs 第 66–77 行同样的输入在length 10下FixedLength输出Text long…而该截断器输出Text with…——因为多出的两个字母额度恰好能装下完整的with。四、五个截断器的选型对照截断器length的含义是否保留完整词标记占额度典型适用场景FixedLength结果总字符数否是标题、表格单元格等严格定宽展示FixedNumberOfCharacters字母/数字个数否是电话号码、编码等字符密度计数FixedNumberOfWords词数以词为整体切是摘要、预览文本固定 N 词DynamicLengthAndPreserveWords结果总字符数是是需要定宽且不出现半词的 UI 标签DynamicNumberOfCharactersAndPreserveWords字母/数字个数是是定宽 保词的复合需求共同的行为契约在 TruncatorTests.cs 各组用例中反复验证null输入恒返回null空串恒返回字符串未超限时原样返回不追加任何标记length恰等于字符串长度或词数/字母数相等时也不截断。五、自定义 ITruncator扩展点与实践由于Truncate扩展方法的全部重载最终都收敛到truncator.Truncate(...)任何需要特殊截断语义如按 Unicode 词边界、按 HTML 标签配对截断、保留尾部完整短语的场景都只需实现ITruncator并传入扩展方法即可无需改动调用侧代码sealed class LastWordOnlyTruncator : ITruncator { public string Truncate(string value, int length, string truncationString, TruncateFrom truncateFrom TruncateFrom.Right) { // 自定义逻辑例如按 LastIndexOf( ) 切出最后一个词再定长截断 ... } } string result The quick brown fox jumps.Truncate( 10, ..., new LastWordOnlyTruncator(), TruncateFrom.Right);实现时需注意与内置实现保持一致的两点契约value为null时返回null接口签名带有NotNullIfNotNull特性编译器会据此检查以及标记长度大于length时降级为不带标记的子串这一内置实现普遍采用的安全退化策略可对照 FixedLengthTruncator.cs 第 21–26 行。六、相关源码与测试索引接口定义src/Humanizer/Truncation/ITruncator.cs静态工厂与五实现src/Humanizer/Truncation/Truncator.cs 及 Truncation 目录扩展方法与默认值src/Humanizer/TruncateExtensions.cs方向枚举src/Humanizer/TruncateFrom.cs全量行为断言tests/Humanizer.Tests/TruncatorTests.cs320 行 Theory 用例覆盖null、空串、等长边界、自定义标记、左右方向对应公开 API 文档Humanizer.ITruncator.md小结ITruncator以单方法 四参数的最小契约承载了 Humanizer 全部字符串截断能力五个内置实现分别对应总长 / 字母数字数 / 词数三种度量与硬切 / 保词两种风格TruncateExtensions则提供了带合理默认值…标记、Right方向、FixedLength截断器的友好入口。理解本文第五节的扩展契约后你可以将任意领域特定的截断逻辑无缝挂入这套 API。赞分享开发工具【免费下载链接】HumanizerHumanizer meets all your .NET needs for manipulating and displaying strings, enums, dates, times, timespans, numbers and quantities项目地址https://gitcode.com/gh_mirrors/hu/Humanizer点击查看免费下载相关推荐Humanizer.ITruncator 接口完全指南掌握 Humanizer 的字符串截断扩展点Humanizer.ITruncator 接口完全指南掌握 Humanizer 的字符串截断扩展点 导读 本文围绕 Humanizer 的 ITruncato开发工具Humanizer ITimeOnlyHumanizeStrategy 接口深度解析自定义 TimeOnly.Humanize 时间人性化策略Humanizer ITimeOnlyHumanizeStrategy 接口深度解析自定义 TimeOnly.Humanize 时间人性化策略 本文以 Hum开发工具Humanizer 时间跨度人性化策略接口 ITimeSpanHumanizeStrategy 深度解析方法签名、参数语义与自定义策略实战Humanizer 时间跨度人性化策略接口 ITimeSpanHumanizeStrategy 深度解析方法签名、参数语义与自定义策略实战 ITimeSpan开发工具上一篇Dart Style完全指南如何用这款革命性格式化工具自动美化你的Dart代码下一篇Go-spew终极指南解决开发者调试过程中的10大常见难题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

opencodex 的 Claude Code 入站加固实战:思考签名往返、错误分类对齐与发布门控(Phase 4)
opencodex 的 Claude Code 入站加固实战:思考签名往返、错误分类对齐与发布门控(Phase 4)

【免费下载链接】opencodex Universal provider proxy for OpenAI Codex & Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code 项目地址: https://gitcode.com/gh_mirrors/ope/opencodex 点击… · 2026/9/25 2:45:30

jc 解析 `host` 命令输出:将 DNS 查询结果转为 JSON 的实用指南
jc 解析 `host` 命令输出:将 DNS 查询结果转为 JSON 的实用指南

开发工具 【免费下载链接】jc CLI tool and python library that converts the output of popular command-line tools, file-types, and common strings to JSON, YAML, or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.… · 2026/9/25 2:45:30

Apereo CAS 认证策略配置详解:Any 策略(cas.authn.policy.any)
Apereo CAS 认证策略配置详解:Any 策略(cas.authn.policy.any)

后端认证鉴权单点登录 【免费下载链接】cas Apereo CAS - Identity & Single Sign On for all earthlings and beyond. 项目地址: https://gitcode.com/gh_mirrors/ca/cas 点击查看 免费下载 在 Apereo CAS 中,"Any 认证策略"是最常见的一… · 2026/9/25 2:45:30

MySQL表空间传输实战:超大单表分钟级迁移原理与踩坑指南
MySQL表空间传输实战:超大单表分钟级迁移原理与踩坑指南

表空间传输这个功能,说实话在很多DBA的日常工具箱里属于"知道但不常用"的那一类。直到有一天我接到一个需求:线上有一张将近200GB的流水表,要从一个MySQL实例迁到另一个新实例,业务方给的窗口只有30分钟。mysqldump导数… · 2026/9/25 3:18:26

OpenShift Source Build 基于 Secret 注解自动注入凭据:`build.openshift.io/source-secret-match-uri-*` 设计机制与实现验证
OpenShift Source Build 基于 Secret 注解自动注入凭据:`build.openshift.io/source-secret-match-uri-*` 设计机制与实现验证

测试云原生质量保障 【免费下载链接】origin Conformance test suite for OpenShift 项目地址: https://gitcode.com/gh_mirrors/or/origin 点击查看 免费下载 导读 本文围绕 OpenShift(Origin)仓库中的设计提案文档 secret-annotation-new… · 2026/9/25 3:18:14

Apereo CAS 集成 Spring Cloud Etcd:外部化配置中心与运行时动态更新实战指南
Apereo CAS 集成 Spring Cloud Etcd:外部化配置中心与运行时动态更新实战指南

后端认证鉴权单点登录 【免费下载链接】cas Apereo CAS - Identity & Single Sign On for all earthlings and beyond. 项目地址: https://gitcode.com/gh_mirrors/ca/cas 点击查看 免费下载 导读 本文面向部署和维护 Apereo CAS 单点登录服务的开发者&#x… · 2026/9/25 3:18:14

小米相机包徕卡/原生相机替换:Magisk模块制作与避坑指南
小米相机包徕卡/原生相机替换:Magisk模块制作与避坑指南

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

Hugo Blox 文档模板实战指南:从项目结构到短代码组件,搭建可维护的 Docs 站点
Hugo Blox 文档模板实战指南:从项目结构到短代码组件,搭建可维护的 Docs 站点

静态站点前端开发工具 【免费下载链接】kit 🧱 Describe your site, AI builds it, you own it as Markdown. Snap together Tailwind blocks like Lego — landing pages, blogs, portfolios, docs & more. No AI slop. Free to deploy anywhere 👇… · 2026/9/25 3:18:14

用 treg 重建 Clay 式邮箱富集瀑布流:40 行脚本、逐调用计价、六个数据源按序兜底
用 treg 重建 Clay 式邮箱富集瀑布流:40 行脚本、逐调用计价、六个数据源按序兜底

后端API网关MCP 服务dsh-plugin 【免费下载链接】treg OpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn 项目地址: https://gitcode.com/GitHub_Trending/treg/treg 点击查看 免费下载 本文基于 treg 仓库中的重建方案文档&#… · 2026/9/25 3:18:08

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

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

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

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

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

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

了解更多?预约专属演示

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

企业微信二维码