ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Humanizer CollectionHumanizeExtensions 完全指南:把 IEnumerable 变成人类可读的自然语言列表

Humanizer CollectionHumanizeExtensions 完全指南:把 IEnumerable 变成人类可读的自然语言列表 开发工具【免费下载链接】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 是一套面向 .NET 的字符串、枚举、日期、时间与数字处理工具库而CollectionHumanizeExtensions负责其中最关键的一环把IEnumerableT集合人化成符合自然语言习惯的列表文本如1, 2 and 3。本文以 CollectionHumanizeExtensions.md 收录的公开 API 为骨架结合 CollectionHumanizeExtensions.cs 源码、CollectionHumanizeTests.cs 测试与各语言 Locale 数据系统讲解 6 个重载的使用方式、自定义格式化函数、分隔符语义、多语言注册机制与底层实现原理。读完本文你将能在自己的 .NET 项目中熟练使用Humanize生成带牛津逗号、符合文化习惯的集合列表并能按需定制集合格式化器。一、类概览与核心职责CollectionHumanizeExtensions是一个静态扩展类签名如下public static class CollectionHumanizeExtensions它继承自System.Object本身不保存任何状态所有方法均为对IEnumerableT的扩展方法作用是把集合Humanizes人化为一个人类可读的列表字符串。其 XML 注释给出的定位是Humanizes an IEnumerable into a human readable list从 CollectionHumanizeExtensions.cs 可以看到类的全部 8 个公开扩展方法文档版本列出 6 个核心重载都只是薄薄的外观层——它们真正的工作全部委托给Configurator.CollectionFormatter当前线程文化对应的集合格式化器这种扩展方法 配置器委托的架构保证了用户只需关心语义分隔符、连词、逗号风格等文化差异由底层 formatter 自动处理。二、六个核心重载签名、参数与返回值该 API 文档共收录 6 个重载它们在是否传入displayFormatter、是否传入separator两个维度上排列组合覆盖了绝大多数使用场景。统一约定如下泛型参数T集合元素类型参数collectionIEnumerableT不能为null否则抛出ArgumentNullException参数displayFormatter逐元素格式化委托两种形态FuncT, string或FuncT, object均不能为null参数separator元素间的分隔字符串返回值string即格式化后的列表文本。重载签名行为①HumanizeT(this IEnumerableT collection)对每个元素调用ToString()使用当前文化的默认分隔符与连词如英文, and②HumanizeT(this IEnumerableT collection, string separator)对每个元素调用ToString()使用调用方提供的分隔符③HumanizeT(this IEnumerableT collection, FuncT, object displayFormatter)用委托格式化每个元素返回值会被转成字符串默认分隔符④HumanizeT(this IEnumerableT collection, FuncT, object displayFormatter, string separator)委托格式化 自定义分隔符⑤HumanizeT(this IEnumerableT collection, FuncT, string displayFormatter)用委托格式化每个元素直接得到字符串默认分隔符⑥HumanizeT(this IEnumerableT collection, FuncT, string displayFormatter, string separator)委托格式化 自定义分隔符1. 无参调用默认文化分隔符public static string HumanizeT(this System.Collections.Generic.IEnumerableT collection);这是最常用的入口。源码中它直接委托给Configurator.CollectionFormatter.Humanize(collection)见 CollectionHumanizeExtensions.cs底层会走o o?.ToString() 默认分隔符的路径DefaultCollectionFormatter.cs。典型输出英文文化new[] { 1, 2, 3 }.Humanize(); // 1, 2 and 3 new[] { Alice, Bob, Charlie }.Humanize(); // Alice, Bob and Charlie new[] { single }.Humanize(); // single new string[] { }.Humanize(); // 注意空集合与单元素集合的边界行为0 个元素返回空字符串1 个元素直接返回该元素本身见 DefaultCollectionFormatter.cs。2. 指定分隔符public static string HumanizeT(this System.Collections.Generic.IEnumerableT collection, string separator);把默认连词替换为任意字符串。底层走Humanize(collection, o o?.ToString(), separator)DefaultCollectionFormatter.csnew[] { 1, 2, 3 }.Humanize( | ); // 1 | 2 | 3 new[] { Alice, Bob }.Humanize(; ); // Alice; Bob测试HumanizeUsesSeparatorWhenMoreThanOneItemIsInCollection验证了collection.Humanize(or)输出A String or Another String见 CollectionHumanizeTests.cs。3/4. 对象形态的 displayFormatterFuncT, objectpublic static string HumanizeT(this System.Collections.Generic.IEnumerableT collection, System.FuncT, object displayFormatter); public static string HumanizeT(this System.Collections.Generic.IEnumerableT collection, System.FuncT, object displayFormatter, string separator);委托返回任意object底层通过objectFormatter(item)?.ToString()转字符串后拼接DefaultCollectionFormatter.cs。适用于只投影不排版的场景var numbers new[] { 1, 2, 3 }; numbers.Humanize(n n * 2); // 2, 4 and 6 numbers.Humanize(n n * 2, - ); // 2 - 4 - 6对应测试HumanizeUsesObjectDisplayFormatter与HumanizeUsesObjectDisplayFormatterWhenSeparatorIsProvidedCollectionHumanizeTests.cs分别验证了1, 2, and 3与1, 2, or 3的输出。5/6. 字符串形态的 displayFormatterFuncT, stringpublic static string HumanizeT(this System.Collections.Generic.IEnumerableT collection, System.FuncT, string displayFormatter); public static string HumanizeT(this System.Collections.Generic.IEnumerableT collection, System.FuncT, string displayFormatter, string separator);委托直接返回字符串适合先排版再拼接的复杂投影比如拼接对象多个字段var people new[] { new Person { Name Alice, Age 30 }, new Person { Name Bob, Age 25 } }; people.Humanize(p p.Name); // Alice and Bob people.Humanize(p ${p.Name} ({p.Age})); // Alice (30) and Bob (25) people.Humanize(p p.Name, | ); // Alice | Bob对应测试HumanizeUsesStringDisplayFormatter与HumanizeUsesStringDisplayFormatterWhenSeparatorIsProvided验证了SomeObject #1 - One, SomeObject #2 - Two, and SomeObject #3 - Three等输出CollectionHumanizeTests.cs。三、null 与空白元素的防御性语义CollectionHumanizeExtensions的重载对委托参数统一做了ArgumentNullException.ThrowIfNull(displayFormatter)防御CollectionHumanizeExtensions.cs。除此之外底层 formatter 还有两条对调用方友好的默认规则见 ICollectionFormatter.cs 的 remarks忽略空/空白项格式化结果为null、空字符串或纯空白IsNullOrWhiteSpace的元素会被直接跳过不参与拼接自动 Trim保留下来的元素会先Trim()再去掉首尾空白。这两条规则在测试中有明确证据// 空元素被移除 Assert.Equal(A and C, StringsWithEmptyItem.Humanize(DummyFormatter)); // [A, , C] // 元素被 Trim Assert.Equal(A, B, and C, StringsWithWhitespace.Humanize(DummyFormatter)); // [A, B , C]见 CollectionHumanizeTests.cs。实现位置在 DefaultCollectionFormatter.csAddDisplayString只接受非空白的Trim()结果。这意味着空集合、全空元素集合都会安全地返回集合中的null元素也不会抛异常测试HumanizeHandlesNullItemsWithoutAnException等予以验证见 CollectionHumanizeTests.cs。四、多文化支持牛津逗号与本地化连词集合人化最体现价值的地方在于文化差异。Humanize默认使用当前线程文化Configurator.CollectionFormatter通过ResolveForCulture(null)解析见 Configurator.cs若需要显式指定文化可调用Humanize(culture)形式的重载它会走Configurator.CollectionFormatters.ResolveForCulture(culture)CollectionHumanizeExtensions.cs且culture为null时同样抛ArgumentNullException测试HumanizeThrowsWhenCultureIsNull验证见 CollectionHumanizeTests.cs。四种集合格式化器实现文化注册表CollectionFormatterRegistryCollectionFormatterRegistry.cs为每个 Locale 解析出一个ICollectionFormatter实现。接口定义了 6 个与扩展方法一一对应的Humanize方法ICollectionFormatter.cs当前仓库共有 4 种实现实现类语义典型示例DefaultCollectionFormatter用默认分隔符 连词拼接前三项, 分隔、末项前用连词A, B and COxfordStyleCollectionFormatter牛津逗号风格3 项及以上在倒数第二项后加逗号A, B, and CCliticCollectionFormatter把末项连词当作附缀clitic与最后一项直接拼写阿拉伯语أ، ب و جو直接缀在末项前DelimitedCollectionFormatter纯分隔符拼接所有可见项之间用同一分隔符中文A、B、C以牛津逗号为例OxfordStyleCollectionFormatter.cs 覆写了GetConjunctionFormatStringprotected override string GetConjunctionFormatString(int itemCount) itemCount 2 ? {0}, {1} {2} : {0} {1} {2};即仅当可显示项 ≥ 3 时在连词前补一个逗号。测试HumanizeUsesOxfordComma验证了A String, Another String, or A Third StringCollectionHumanizeTests.cs。Locale 数据如何驱动格式化器集合格式化器的选择并非硬编码在代码里而是来自各语言的Locales/*.yml数据。每个 Locale 文件都含list:配置节例如英文en.yml使用engine: oxford即英文默认就是牛津逗号风格法语fr.yml使用engine: conjunctionvalue: et连词为法语和简体中文zh-Hans.yml使用engine: delimitedvalue: 、即中文顿号分隔阿拉伯语ar.yml使用engine: cliticvalue: و把连词作为附缀直接缀在末项前。这些 YAML 配置在编译期由源生成器读取HumanizerSourceGenerator中的 GenerationHelpers.cs 根据list.engine生成对应的 formatter 构造代码oxford→OxfordStyleCollectionFormatter、conjunction→DefaultCollectionFormatter、clitic→CliticCollectionFormatter、delimited→DelimitedCollectionFormatter。因此新增一种集合风格只需要在 Locale YAML 中声明无需改动运行时代码。五、注册表结构与扩展机制若想为某个文化自定义集合格式化行为理解注册表结构是关键。CollectionFormatterRegistry继承自LocaliserRegistryICollectionFormatter其默认构造逻辑是public CollectionFormatterRegistry() : base(_ new DefaultCollectionFormatter()) CollectionFormatterRegistryRegistrations.Register(this);见 CollectionFormatterRegistry.cs。两点值得注意兜底默认值未显式匹配任何文化的解析结果会得到以为连词的DefaultCollectionFormatter注册由源生成器填充CollectionFormatterRegistryRegistrations.Register(this)是由Humanizer.SourceGenerators在编译期生成的注册代码把每个 Locale 的 formatter 实例写入注册表——这也是为什么 YAML 数据能驱动运行时的原因。对外Configurator.CollectionFormatters属性暴露了LocaliserRegistryICollectionFormatterConfigurator.cs你可以仿照 Humanizer 其它注册表如FormatterRegistry、NumberToWordsConverterRegistry的做法通过注册表注入自定义ICollectionFormatter实现从而覆盖任意文化的列表风格。六、性能与实现细节源码视角从源码结构看四种实现都对少元素路径做了刻意优化DefaultCollectionFormatter对 0/1 个可见元素直接返回不做字符串格式化2 项与多项通过JoinLeadingItems拼接前导项、最后用GetConjunctionFormatString收尾DefaultCollectionFormatter.csDelimitedCollectionFormatter用StringBuilder统一追加分隔符并把首个可见项留在 builder 之外使单元素路径零分配DelimitedCollectionFormatter.csCliticCollectionFormatter类似地先持有首项、再把倒数第二项并入逗号头部末项保持独立以便连词附缀化CliticCollectionFormatter.cs。此外CreateDisplayItems会根据集合是否实现ICollectionT/IReadOnlyCollectionT预分配容量避免不必要的扩容DefaultCollectionFormatter.cs。七、实战速查常见调用模式需求代码输出en 文化简单列表new[] { A, B, C }.Humanize()A, B, and C自定义分隔符new[] { A, B }.Humanize( or )A or B投影数值new[] { 1, 2, 3 }.Humanize(n n * 2)2, 4, and 6投影并排版people.Humanize(p ${p.Name} ({p.Age}))Alice (30) and Bob (25)指定文化new[] { A, B, C }.Humanize(new CultureInfo(en-GB))A, B and C空集合Array.Emptyint().Humanize()测试HumanizeUsesSpecifiedCulture验证了en-GB下三元素输出A, B and CCollectionHumanizeTests.cs而HumanizeUsesSpecifiedCultureForEverySupportedLocale则对所有支持语言逐语言断言两元素/三元素的输出CollectionHumanizeTests.cs可作为你验证多语言行为的第一手参考。总结CollectionHumanizeExtensions以 6 个轻量重载覆盖了集合列表人化的全部常用场景默认文化、自定义分隔符、字符串/对象两种投影委托并且通过ICollectionFormatter Locale YAML 源生成器的组合让牛津逗号、法语et、阿拉伯语附缀و、中文顿号、等文化差异在运行时自动生效。理解 CollectionHumanizeExtensions.cs 的委托结构、ICollectionFormatter.cs 的接口契约与 CollectionHumanizeTests.cs 的边界用例即可在项目中放心使用也能按需扩展自己的列表风格。赞分享开发工具【免费下载链接】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 CollectionHumanizeExtensions 集合人性化指南让 IEnumerable 输出变成自然语言列表Humanizer CollectionHumanizeExtensions 集合人性化指南让 IEnumerable 输出变成自然语言列表 导读 Colle开发工具Humanizer 完全指南用 .NET 库把字符串、枚举、日期与数量变成人类可读文本Humanizer 完全指南用 .NET 库把字符串、枚举、日期与数量变成人类可读文本 Humanizer 是一个面向 .NET 的文本人性化库专门把字符串开发工具Humanizer DateHumanizeExtensions 深度解析把 DateTime / DateOnly / TimeOnly 变成3 days ago式自然语句Humanizer DateHumanizeExtensions 深度解析把 DateTime / DateOnly / TimeOnly 变成3 days开发工具上一篇ElasticJob任务重试策略终极指南固定间隔与指数退避对比分析下一篇aimeos-laravel商品搜索排序相关性算法优化实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表