ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Humanizer IOrdinalizer 接口详解:本地化序数词(1st / 1º / 1.er)转换的扩展点与实现原理

Humanizer IOrdinalizer 接口详解:本地化序数词(1st / 1º / 1.er)转换的扩展点与实现原理 开发工具【免费下载链接】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 3.0.8 版本 API 文档Humanizer.IOrdinalizer.md为核心系统讲解IOrdinalizer接口的四个Convert重载、参数语义与返回约定并结合仓库源码剖析它在Ordinalize扩展方法中的真实调用链、内置实现类以及基于OrdinalizerRegistry的本地化注册机制。读完本文你将能够正确调用Ordinalize()的各类重载处理文化差异、语法性别与词形变体理解 64 位整数序数化的扩展方式并能自行实现并注册一个符合 Humanizer 规范的本地化序数转换器。一、接口定位本地化Ordinalize方法的扩展点IOrdinalizer是 Humanizer 中负责将数字本地化为序数形式的抽象接口即把1转换为1st、1º、1.er这类表示有序序列中位置的字符串。它并不直接暴露给日常 API 调用者——日常使用是通过OrdinalizeExtensions提供的各种重载触发的——但它定义了所有语言序数规则实现的统一契约。接口的官方定义位于 src/Humanizer/Localisation/Ordinalizers/IOrdinalizer.cspublic interface IOrdinalizer { string Convert(int number, string numberString); string Convert(int number, string numberString, WordForm wordForm); string Convert(int number, string numberString, GrammaticalGender gender); string Convert(int number, string numberString, GrammaticalGender gender, WordForm wordForm); }四个重载的语义差异非常明确重载作用典型适用场景Convert(int, string)使用默认语法形式序数化数字英语1 - 1st、德语1 - 1.Convert(int, string, WordForm)按地区特定词形正常/缩写序数化西班牙语1 - 1.º正常vs1 - 1.er缩写Convert(int, string, GrammaticalGender)使用指定语法性别序数化巴西葡萄牙语1 - 1º阳性vs1 - 1ª阴性Convert(int, string, GrammaticalGender, WordForm)同时考虑性别与词形西班牙语1 - 1.er阳性缩写、1 - 1.ª阴性正常在 API 文档中这四个方法分别对应 Convert(int, string) 至 Convert(int, string, GrammaticalGender, WordForm) 四个条目每个条目都声明返回类型为System.StringSystem.String。二、方法签名逐项解析2.1Convert(int number, string numberString)string Convert(int number, string numberString);numberSystem.Int32被序数化的数值本身。它是整数用于触发规则判定如0的特殊处理、取绝对值的末位数字等。numberStringSystem.String该数值的基数cardinal字符串表示例如1、21、-3。实现类通常以拼接方式将其作为序数输出的主体再把后缀、前缀附加其上。返回值string即序数化后的文本。该方法是接口的最基础契约。以英语实现为例Convert(1, 1)应返回1st、Convert(22, 22)应返回22nd。2.2Convert(int number, string numberString, GrammaticalGender gender)string Convert(int number, string numberString, Humanizer.GrammaticalGender gender);在number、numberString之上增加了 GrammaticalGender 参数。语法性别GrammaticalGender.cs 中定义包含Masculine阳性、Feminine阴性、Neuter中性等取值。只有需要按性别区分序数形式的语言才依赖此参数例如巴西葡萄牙语中1.Ordinalize(GrammaticalGender.Masculine)输出1º而1.Ordinalize(GrammaticalGender.Feminine)输出1ª。多数语言如英语对性别不敏感实现上直接忽略该参数。2.3Convert(int number, string numberString, WordForm wordForm)string Convert(int number, string numberString, Humanizer.WordForm wordForm);增加了 WordForm 参数用于在同一语言存在不同词形变体时选择输出形式。WordForm枚举定义于 src/Humanizer/WordForm.cs取值如下取值含义Normal单词的正常书写形式Abbreviation单词的缩写形式Eifeler遵循 Eifeler 规则的词形卢森堡语特有参见 EifelerRule.cs西班牙语是典型例子1.Ordinalize(WordForm.Abbreviation)返回1.er如 Vivo en el 1.er piso而1.Ordinalize(WordForm.Normal)返回1.º如 Fui el 1º de mi promoción。该重载的语义在 API 文档中描述为 Ordinalizes the number to a locales specific form序数化到地区特定的形式。2.4Convert(int number, string numberString, GrammaticalGender gender, WordForm wordForm)string Convert(int number, string numberString, Humanizer.GrammaticalGender gender, Humanizer.WordForm wordForm);四个参数的完整组合同时应用语法性别与词形变体。API 文档对其描述为 Ordinalizes the number to a locales specific form using the provided grammatical gender。西班牙语的完整示例来自 OrdinalizeExtensions.cs 的 XML 文档注释1.Ordinalize(GrammaticalGender.Masculine, WordForm.Abbreviation) // - 1.er Vivo en el 1.er piso 1.Ordinalize(GrammaticalGender.Masculine, WordForm.Normal) // - 1.º Fui el 1º de mi promoción 1.Ordinalize(GrammaticalGender.Feminine, WordForm.Normal) // - 1.ª Es 1ª vez que hago esto三、调用链从Ordinalize()到IOrdinalizer.ConvertIOrdinalizer由扩展方法类 OrdinalizeExtensions.cs 统一驱动。以最简单的字符串重载为例public static string Ordinalize(this string numberString) Configurator.Ordinalizer.Convert(int.Parse(numberString), NormalizeOrdinalNumberString(numberString));执行流程为int.Parse(numberString)将字符串解析为整数值numberNormalizeOrdinalNumberString(numberString)去除字符串中所有UnicodeCategory.Format类字符如零宽空格、双向控制符等格式字符得到干净的基数文本通过Configurator.Ordinalizer获取当前线程文化对应的IOrdinalizer实例并调用Convert。而带文化参数的重载则走注册表路径public static string Ordinalize(this string numberString, CultureInfo? culture) { var resolvedCulture culture ?? CultureInfo.CurrentCulture; return Configurator.Ordinalizers.ResolveForCulture(culture) .Convert(ParseOrdinalNumber(numberString, resolvedCulture), NormalizeOrdinalNumberString(numberString)); }这里Configurator.Ordinalizers是一个OrdinalizerRegistry实例Configuration/OrdinalizerRegistry.cs它继承自LocaliserRegistryIOrdinalizer构造时以new DefaultOrdinalizer()作为默认回退并通过OrdinalizerRegistryRegistrations.Register(this)批量注册各语言的实现。整数重载int/long与字符串重载有一个关键差异整数会先用目标文化的NumberFormat格式化为字符串FormatOrdinalNumberString再交给转换器long重载还会通过ConvertOrdinalizer辅助方法做类型适配详见下文。3.1long与ILongOrdinalizer64 位序数化IOrdinalizer本身只接受int但 Humanizer 在 IOrdinalizer.cs 中额外定义了ILongOrdinalizer : IOrdinalizer子接口为支持超出int范围的数值提供long版本的同名重载。OrdinalizeExtensions中的ConvertOrdinalizer辅助方法体现了适配逻辑OrdinalizeExtensions.cs若当前注册的序数化器实现了ILongOrdinalizer直接调用其long重载否则回退到IOrdinalizer的int重载若数值超出int范围则抛出NotSupportedException提示已注册的序数化器不支持 64 位值。测试用例 tests/Humanizer.Tests/OrdinalizeTests.cs 验证了这一行为2_147_483_651L.Ordinalize()在英语下输出2147483651stlong路径而2147483648.Ordinalize()字符串重载走int.Parse会抛出OverflowException。同时测试还断言了21.Ordinalize(culture)与21L.Ordinalize(culture)的结果一致性以及long.MinValue在es-ES、ca-ES等文化下的行为如抛出异常或按负值规则处理。四、内置实现类一套可复用的规则引擎接口之下仓库在 src/Humanizer/Localisation/Ordinalizers/ 目录提供了一批内置实现全部继承自DefaultOrdinalizerDefaultOrdinalizer.cs。DefaultOrdinalizer是一个透传基类所有重载默认直接返回numberString原样并统一以long为中心实现相互转发例如Convert(int, string)内部转为long后调用同时提供GetAbsoluteValue安全计算绝对值与TryGetInt32Value范围检测两个受保护辅助方法。各内置实现类及其规则策略实现类策略代表语言从注册表推断SuffixOrdinalizer为阳性/阴性/中性分别配置固定后缀拼接在numberString之后支持zeroAsPlainNumber0 输出为0使用单一后缀的语言如德语1.ModuloSuffixOrdinalizer按取模结果选择后缀英语st/nd/rd/th这类按末尾数字分支的规则TemplateOrdinalizer按性别配置前缀 默认后缀 精确替换表 精确后缀表 末位数字后缀表规则较多的语言WordFormTemplateOrdinalizer在模板基础上按Normal/Abbreviation词形各维护一套模式PatternSet并支持三种负数模式西班牙语、加泰罗尼亚语等区分词形的语言NumberWordSuffixOrdinalizer依赖数字转单词NumberToWords的结果做后缀特定语言以WordFormTemplateOrdinalizer为例WordFormTemplateOrdinalizer.cs其Convert的判定优先级是zeroAsPlainNumber且number 0→ 返回0minValueAsPlainNumber且number int.MinValue→ 返回0负数按NegativeModeNone/AbsoluteInvariant/AbsoluteCulture归一化命中ExactReplacements精确替换表 → 直接返回替换文本命中ExactSuffixes精确后缀表 → 输出前缀 numberString 精确后缀命中LastDigitSuffixes末位数字表 → 输出前缀 numberString 末位后缀兜底 → 输出前缀 numberString DefaultSuffix。TemplateOrdinalizerTemplateOrdinalizer.cs逻辑相同但不区分词形只有一套按性别划分的模式。Pattern记录结构体Prefix/DefaultSuffix/ExactReplacements/ExactSuffixes/LastDigitSuffixes本身就是一份完整的序数规则描述各语言注册时只需按此结构填表。五、注册机制本地化器如何被解析OrdinalizerRegistry继承自 LocaliserRegistry.cs其解析策略决定了IOrdinalizer的实例化方式默认回退构造函数指定_ new DefaultOrdinalizer()未注册的文化一律得到透传默认实现注册Register(localeCode, localiser)在首次使用前将文化码映射到实例或工厂函数LocaliserRegistry首次解析时会把字典冻结为FrozenDictionary以提升读取性能冻结后即registry has been used之后再注册会抛出InvalidOperationException解析ResolveForCulture(culture)借助ConditionalWeakTableCultureInfo, StrongBoxTLocaliser做实例级缓存未命中时沿culture.Parent链向上回溯如es-MX → es → 默认保证父文化回退生成式解析启用UseGeneratedCultureResolver后先查精确文化码失败则委托GeneratedCultureResolver依据预生成的本地化配置文件对应 src/Humanizer.SourceGenerators 生成的目录解析文化归属。日常开发中如需为自定义文化注入序数规则只需实现IOrdinalizer或继承DefaultOrdinalizer只重写需要的重载后调用Configurator.Ordinalizers.Register(...)注册即可无需改动 Humanizer 源码。六、参数与返回值速查将 API 文档与源码交叉核对后IOrdinalizer各成员的契约可归纳如下成员签名参数返回值Convert#1Convert(int number, string numberString)number: 数值numberString: 基数文本默认语法形式的序数文本Convert#2Convert(int number, string numberString, GrammaticalGender gender)另加gender: 语法性别按性别区分的序数文本Convert#3Convert(int number, string numberString, WordForm wordForm)另加wordForm: 词形Normal/Abbreviation/Eifeler按词形区分的序数文本Convert#4Convert(int number, string numberString, GrammaticalGender gender, WordForm wordForm)性别 词形组合同时考虑性别与词形的序数文本七、注意事项与边界仅接受整数值OrdinalizeExtensions的文档注释明确指出 Ordinalization accepts integral values only序数化仅接受整数值。小数等非整数值必须先由调用方显式执行取整与类型转换策略再交给Ordinalize字符串重载通过int.Parse默认文化解析越界将抛出OverflowException测试OrdinalizeTests.cs中2147483648.Ordinalize()一例即是佐证。格式字符剥离转换前NormalizeOrdinalNumberString会剔除UnicodeCategory.Format类字符确保 RTL 语言中嵌入的双向控制符等不污染输出。数字渲染与文化的耦合整数重载使用目标文化的NumberFormat渲染数字文本如负数符号、本地数字位数因此(-1).Ordinalize(culture)与(-1).ToString(culture).Ordinalize(culture)在测试中被断言为相等非不变文化的数字系统如使用NativeDigits的语言也由UsesInvariantDigits检测统一处理见 OrdinalizeExtensions.cs。接口稳定性IOrdinalizer的int重载保持 32 位契约ILongOrdinalizer是面向 64 位场景的演进接口两者并存、向后兼容注册表中已有的IOrdinalizer实现依然适用于 32 位数值。八、扩展阅读接口源码src/Humanizer/Localisation/Ordinalizers/IOrdinalizer.cs扩展方法入口src/Humanizer/OrdinalizeExtensions.cs注册表与解析src/Humanizer/Configuration/OrdinalizerRegistry.cs、src/Humanizer/Configuration/LocaliserRegistry.cs内置实现src/Humanizer/Localisation/Ordinalizers/相关枚举GrammaticalGender.cs、WordForm.cs行为验证tests/Humanizer.Tests/OrdinalizeTests.cs关联 API 文档Humanizer.GrammaticalGender.md、Humanizer.WordForm.md赞分享开发工具【免费下载链接】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 IOrdinalizer 接口详解自定义本地化序数词转换的扩展点Humanizer IOrdinalizer 接口详解自定义本地化序数词转换的扩展点 本篇技术指南以 Humanizer 仓库中 Humanizer.Loca开发工具Humanizer IOrdinalizer 接口深度解析本地化序数词生成的扩展点与实现原理Humanizer IOrdinalizer 接口深度解析本地化序数词生成的扩展点与实现原理 IOrdinalizer 是 Humanizer 中负责把数字转开发工具Humanizer 本地化序数词引擎IOrdinalizer 接口的契约、实现与扩展实战指南Humanizer 本地化序数词引擎IOrdinalizer 接口的契约、实现与扩展实战指南 Humanizer 是面向 .NET 的字符串、枚举、日期与数字开发工具上一篇Dify Docker Compose 部署实战指南三层 .env 配置体系、中间件开发环境与变量同步工具下一篇sunnyhunter/GitCode-SeeAI-01-040智能助手对话式景点推荐的实现方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表