比较c#中的两个字符串是否相等,InvariantCulture和Ordinal比较之间有什么区别?
使用"标准"字符排序集(a,b,c,......等).这与某些特定区域设置形成对比,这些区域设置可以按不同顺序对字符进行排序("a-with-acute"可以在'a' 之前或之后,具体取决于区域设置,依此类推).
另一方面,看起来纯粹是表示字符的原始字节的值.
http://msdn.microsoft.com/en-us/library/e6883c06.aspx上有一个很好的示例,它显示了各种StringComparison值的结果.一直到最后,它显示(摘录):
StringComparison.InvariantCulture: LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131) LATIN SMALL LETTER I (U+0069) is less than LATIN CAPITAL LETTER I (U+0049) LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049) StringComparison.Ordinal: LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131) LATIN SMALL LETTER I (U+0069) is greater than LATIN CAPITAL LETTER I (U+0049) LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049)
您可以看到InvariantCulture的收益率(U + 0069,U + 0049,U + 00131),序数收益率(U + 0049,U + 0069,U + 00131).
例如,它确实很重要 - 有一种叫做角色扩展的东西
var s1 = "Strasse"; var s2 = "Straße"; s1.Equals(s2, StringComparison.Ordinal); //false s1.Equals(s2, StringComparison.InvariantCulture); //true
随着InvariantCulture
ß角色扩展到ss.
指向在.NET Framework中使用字符串的最佳实践:
使用StringComparison.Ordinal
或StringComparison.OrdinalIgnoreCase
进行比较作为与文化无关的字符串匹配的安全默认值.
使用比较StringComparison.Ordinal
或StringComparison.OrdinalIgnoreCase
获得更好的性能.
基于比较在语言上无关的时间(例如,符号),使用非语言StringComparison.Ordinal
或StringComparison.OrdinalIgnoreCase
值而不是字符串操作CultureInfo.InvariantCulture
.
最后:
StringComparison.InvariantCulture
在大多数情况下,不要使用基于字符串的操作.少数例外情况之一是当你坚持语言上有意义但文化上不可知的数据时.
另一个方便的区别(在英语中,重音不常见)是InvariantCulture比较首先按不区分大小写比较整个字符串,然后在必要时(和请求)在首先仅对不同的字母进行比较之后进行区分.(当然,您也可以进行不区分大小写的比较,这不会因情况而区分.) 更正:重音字母被认为是相同字母的另一种风格,字符串首先忽略重音,然后在一般字母全部匹配的情况下进行比较(与不同情况一样,除非在不区分大小写的比较中最终忽略).这将其他相同单词的重音版本分组,而不是在第一个重音差异处完全分开.这是您通常在字典中找到的排序顺序,大写单词出现在它们的小写等价物旁边,重音字母靠近相应的非重音字母.
序数比较严格地比较数字字符值,在第一个差异处停止.这种大写字母与小写字母(以及可能与这些字母分开的重音字母)完全分开,因此大写单词在其小写等价物附近排序.
InvariantCulture还认为大写字母大于小写字母,而Ordinal认为大写字母小于小写字母(从计算机使用小写字母之前的旧日期中保留ASCII,大写字母首先被分配,因此其值低于小写字母后来添加).
例如,Ordinal: "0" < "9" < "A" < "Ab" < "Z" < "a" < "aB" < "ab" < "z" < "Á" < "Áb" < "á" < "áb"
并通过InvariantCulture: "0" < "9" < "a" < "A" < "á" < "Á" < "ab" < "aB" < "Ab" < "áb" < "Áb" < "z" < "Z"
虽然问题是关于平等,但为了快速视觉参考,这里使用一些文化排序的一些字符串的顺序说明了那里的一些特质.
Ordinal 0 9 A Ab a aB aa ab ss Ä Äb ß ä äb ? ? ? ? ? ? IgnoreCase 0 9 a A aa ab Ab aB ss ä Ä äb Äb ß ? ? ? ? ? ? -------------------------------------------------------------------- InvariantCulture 0 9 a A ? ä Ä aa ab aB Ab äb Äb ss ß ? ? ? ? ? IgnoreCase 0 9 A a ? Ä ä aa Ab aB ab Äb äb ß ss ? ? ? ? ? -------------------------------------------------------------------- da-DK 0 9 a A ? ab aB Ab ss ß ä Ä äb Äb aa ? ? ? ? ? IgnoreCase 0 9 A a ? Ab aB ab ß ss Ä ä Äb äb aa ? ? ? ? ? -------------------------------------------------------------------- de-DE 0 9 a A ? ä Ä aa ab aB Ab äb Äb ß ss ? ? ? ? ? IgnoreCase 0 9 A a ? Ä ä aa Ab aB ab Äb äb ss ß ? ? ? ? ? -------------------------------------------------------------------- en-US 0 9 a A ? ä Ä aa ab aB Ab äb Äb ß ss ? ? ? ? ? IgnoreCase 0 9 A a ? Ä ä aa Ab aB ab Äb äb ss ß ? ? ? ? ? -------------------------------------------------------------------- ja-JP 0 9 a A ? ä Ä aa ab aB Ab äb Äb ß ss ? ? ? ? ? IgnoreCase 0 9 A a ? Ä ä aa Ab aB ab Äb äb ss ß ? ? ? ? ?
观察:
de-DE
,ja-JP
并en-US
以相同的方式排序
Invariant
只有ss
与ß
上述三种文化不同并且不同
da-DK
完全不同的排序
在IgnoreCase
所有抽样文化标志事项
用于生成上表的代码:
var l = new List{ "0", "9", "A", "Ab", "a", "aB", "aa", "ab", "ss", "ß", "Ä", "Äb", "ä", "äb", "?", "?", "?", "?", "?", "?" }; foreach (var comparer in new[] { StringComparer.Ordinal, StringComparer.OrdinalIgnoreCase, StringComparer.InvariantCulture, StringComparer.InvariantCultureIgnoreCase, StringComparer.Create(new CultureInfo("da-DK"), false), StringComparer.Create(new CultureInfo("da-DK"), true), StringComparer.Create(new CultureInfo("de-DE"), false), StringComparer.Create(new CultureInfo("de-DE"), true), StringComparer.Create(new CultureInfo("en-US"), false), StringComparer.Create(new CultureInfo("en-US"), true), StringComparer.Create(new CultureInfo("ja-JP"), false), StringComparer.Create(new CultureInfo("ja-JP"), true), }) { l.Sort(comparer); Console.WriteLine(string.Join(" ", l)); }
不变量是一种语言上适当的比较类型.
序数是二元类型的比较.(更快)
参见http://www.siao2.com/2004/12/29/344136.aspx
这是一个示例,其中使用InvariantCultureIgnoreCase和OrdinalIgnoreCase进行的字符串相等比较不会给出相同的结果:
string str = "\xC4"; //A with umlaut, Ä string A = str.Normalize(NormalizationForm.FormC); //Length is 1, this will contain the single A with umlaut character (Ä) string B = str.Normalize(NormalizationForm.FormD); //Length is 2, this will contain an uppercase A followed by an umlaut combining character bool equals1 = A.Equals(B, StringComparison.OrdinalIgnoreCase); bool equals2 = A.Equals(B, StringComparison.InvariantCultureIgnoreCase);
如果运行此命令,则equals1将为false,equals2将为true。