Unicode toUppercase与OrdinalIgnoreCase / InvariantCultureIgnoreCase

时间:2017-12-06 12:58:57

标签: c# unicode

根据Unicode字符U + 0131 LATIN SMALL LETTER DOTLESS I的ASCII字符为大写字母' I' 和角色U + 017F'' LATIN SMALL LETTER LONG S的ASCII字符大小为' S'

以下代码在两项检查中均失败

string check = "\u0131\u017F";
if ( string.Equals( check, "IS",StringComparison.OrdinalIgnoreCase ) ) {
    Console.WriteLine( "Ok!" );
}
if ( string.Equals( check, "IS", StringComparison.InvariantCultureIgnoreCase ) ) {
    Console.WriteLine( "Ok!" );
}

鉴于UnicodeData.txt中定义的Unicode toUppercase映射不是语言的,而是不变的,OrdinalIgnoreCase和InvariantCultureIgnoreCase遵循的规则究竟是什么?

1 个答案:

答案 0 :(得分:0)

我没有找到任何稳定的逻辑来解释OrdinalIgnoreCase的行为,我决定使用暴力破解并编写自定义Mapper类来处理比较和获取char * segment的哈希码。

这样做的原因是为最近引入的ReadOnlySpan支持OrdinalIgnoreCase比较和等式检查,并且可能稍后实现可以接受来自字符串和ReadOnlySpan的查找的字符串Dictionary

Mapper的早期版本在OrdinalIgnoreCase.Map.cs

提交

当Compare和Equal测试通过时,GetHashCode因Unicode块Deseret上的某些不一致行为而失败。似乎OrdinalIgnoreCase的GetHashCode算法将Deseret的小写字母转换为高位,而Equals和Compare则不是。您可以在Deseret.cs

的代码中观察到该行为