.NET Core中为何"0".StartsWith("\x1d")返回true?
在.NET Framework中,执行代码"0".StartsWith("\x1d")会返回false;但在.NET Core 7中,相同代码的返回结果为true。本文解释该行为变更的核心原因(已知可通过string.StartsWith(char)或指定StringComparison.Ordinal参数规避此问题)。
这个差异本质是*.NET平台对Unicode排序规则的实现更新,以及默认字符串比较逻辑的调整*,具体细节如下:
Unicode规范版本升级
\x1d对应Unicode码点U+001D(信息分隔符三组),在新版Unicode排序算法(UTS#10)中,这类控制字符被归类为*「非显著排序元素」*——也就是在语言相关的字符串比较中会被忽略的字符。
.NET Framework依赖的Unicode版本较低,对U+001D这类控制字符的处理逻辑是将其视为具有实际权重的字符,因此"0"和"\x1d"的比较不会匹配。默认字符串比较逻辑的对齐
在.NET Core及后续版本中,.NET团队全面升级了Unicode标准的实现,同时调整了默认字符串比较(未指定StringComparison参数时)的逻辑,让其严格遵循最新的Unicode排序规则。当调用"0".StartsWith("\x1d")时,比较逻辑会自动忽略"\x1d"这个可忽略字符,相当于判断"0"是否以空字符串开头,因此返回true。
额外说明:当使用StringComparison.Ordinal时,比较完全基于字符的原始码点值,不会进行任何规范化或忽略处理,所以无论哪个.NET版本,"0".StartsWith("\x1d", StringComparison.Ordinal)都会返回false,这也是规避该差异的有效方式。
内容的提问来源于stack exchange,提问作者Mitch

