.NET 5.0中string.Compare(String, Int32, String, Int32, Int32)方法在泰语文化下比较结果异常
泰语文化下
string.Compare返回0而非-1的原因及解决办法 这个问题我之前碰到过类似场景,本质是泰语本地化排序规则的特殊处理导致的——在th-TH文化的默认排序逻辑里,#和;被视为排序等效的字符,所以string.Compare会返回0,而非你预期的-1。
具体原因
泰语的排序规则基于Unicode排序算法(UCA)做了本地化调整,其中部分标点符号的排序权重被设置为完全相同。对应到你的例子:
#的Unicode码点是U+0023;的Unicode码点是U+003B
在th-TH文化的排序表中,这两个字符的核心排序权重一致,所以调用默认使用当前文化规则的string.Compare时,会判定两者相等。
你可以通过SortKey直观验证这一点:
var culture = new CultureInfo("th-TH"); var sortKeyForHash = culture.CompareInfo.GetSortKey("#"); var sortKeyForSemicolon = culture.CompareInfo.GetSortKey(";"); // 输出两个SortKey的字节数据,会发现核心排序部分完全相同 Console.WriteLine(BitConverter.ToString(sortKeyForHash.KeyData)); Console.WriteLine(BitConverter.ToString(sortKeyForSemicolon.KeyData));
解决办法
根据你的实际需求,有两种常用处理方式:
- 使用序号比较(忽略本地化):如果你不需要遵循泰语的排序逻辑,只是想基于字符的原始码点做比较,直接指定
StringComparison.Ordinal重载即可:int result = string.Compare(value1, 0, value2, 0, 1, StringComparison.Ordinal); // 此时返回-1,因为#的ASCII码(35)小于;的ASCII码(59) - 自定义排序规则:如果必须保留泰语文化的大部分排序逻辑,但要区分这两个字符,可以创建自定义的
CompareInfo,不过这种方式复杂度较高,仅适合特殊场景。
内容的提问来源于stack exchange,提问作者Rahul B
相关产品推荐
相关产品推荐

