s2是标准化的s1
因为字符串s1和s2看起来相同
s1和s2有不同的GetHashCode
String.Compare将s1和s2显示为等效的
s2作为字符串具有重音
s2.ToCharArray删除重音
为什么s2.ToCharArray与s2的字符串不同?
我明白了。
s2的长度为4.
重音只是作为一个单独的字符被删除(Int16 = 769)
String.Compare很聪明,可以搞清楚。
有趣的是,String.Compare计算出来但String.Contains没有。
string s1 = "xxé";
string s1copy = "xxé";
string s2 = s1.Normalize(NormalizationForm.FormD);
string s2b = "xxe";
char accent = 'é';
Debug.WriteLine(s1); // xxé
Debug.WriteLine(s2); // xxé
Debug.WriteLine(s2b); // xxe
Debug.WriteLine(s1.GetHashCode()); // 424384421
Debug.WriteLine(s1copy.GetHashCode()); // 424384421
Debug.WriteLine(s2.GetHashCode()); // 1057341801
Debug.WriteLine(s2b.GetHashCode()); // 1701495145
Debug.WriteLine(s1.Contains(accent)); // true
Debug.WriteLine(s2.Contains(accent)); // false
Debug.WriteLine(s2b.Contains(accent)); // false
Debug.WriteLine(string.Compare(s1, s1copy).ToString()); // 0
Debug.WriteLine(string.Compare(s1, s2).ToString()); // 0
Debug.WriteLine(string.Compare(s1, s2b).ToString()); // 1
Debug.WriteLine(string.Compare(s2, s2b).ToString()); // 1
Debug.WriteLine(s1.Equals(s1copy)); // true
Debug.WriteLine(s1.Equals(s2)); // false
Debug.WriteLine(s1.Equals(s2b)); // false
Debug.WriteLine(s2.Equals(s2b)); // false
Debug.WriteLine(s1 == s1copy); // true
Debug.WriteLine(s1 == s2); // false
Debug.WriteLine(s1 == s2b); // false
Debug.WriteLine(s2 == s2b); // false
char[] chars1 = s1.ToCharArray();
char[] chars2 = s2.ToCharArray();
char[] chars2b = s2b.ToCharArray();
Debug.WriteLine(chars1.Length.ToString()); // 3
Debug.WriteLine(chars2.Length.ToString()); // 4
Debug.WriteLine(chars2b.Length.ToString()); // 3
Debug.WriteLine(chars1[0].ToString() + " " + ((Int16)chars1[0]).ToString() + " " + chars1[1].ToString() + " " + ((Int16)chars1[1]).ToString() + " " + chars1[2].ToString() + " " + ((Int16)chars1[2]).ToString());
// x 120 x 120 é 233
Debug.WriteLine(chars2[0].ToString() + " " + ((Int16)chars2[0]).ToString() + " " + chars2[1].ToString() + " " + ((Int16)chars2[1]).ToString() + " " + chars2[2].ToString() + " " + ((Int16)chars2[2]).ToString() +" " + chars2[3].ToString() + " " + ((Int16)chars2[3]).ToString());
//x 120 x 120 e 101 ́ 769
Debug.WriteLine(chars2b[0].ToString() + " " + ((Int16)chars2b[0]).ToString() + " " + chars2b[1].ToString() + " " + ((Int16)chars2b[1]).ToString() + " " + chars2b[2].ToString() + " " + ((Int16)chars2b[2]).ToString());
//x 120 x 120 e 101
Debug.WriteLine(chars1.GetHashCode()); // 16098066
Debug.WriteLine(chars2.GetHashCode()); // 53324351
Debug.WriteLine(chars2b.GetHashCode()); // 50785559
Debug.WriteLine(chars1 == chars2); // false
Debug.WriteLine(chars1 == chars2b); // false
Debug.WriteLine(chars2 == chars2b); // false
答案 0 :(得分:3)
为什么s2.ToCharArray与s2的字符串不同?
这是因为您选择了NormalizationForm
。它会将xxé
分解为 x , x , e 和`
表示使用完整规范标准化Unicode字符串 分解。
如果仍然不清楚,这里有Unicode Composition
的定义在Unicode的上下文中,字符组合是其过程 替换基本字母的代码点,后跟一个或多个 将字符组合成一个预先组合的字符;和 字符分解是相反的过程。
基本上,你将字符串分解为最低形式,这是你看到的四个不同的字符。
如果你尝试重新组合char[]
var s2Compare = new string(chars2)
var isEq = (s2Compare == s2) //true