不变文化与序数string比较的区别
比较c#中的两个string是否相等,InvariantCulture和Ordinal比较有什么区别?
InvariantCulture的
使用“标准”字符sorting集(a,b,c,…等)。 这与一些特定的区域设置形成对比,这些区域设置可以按照不同的顺序对字符进行sorting(“a-with-sharp”可以在“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中使用string的最佳实践 :
- 使用
StringComparison.Ordinal
或StringComparison.OrdinalIgnoreCase
进行比较,作为文化无关string匹配的安全默认值。 - 使用与
StringComparison.Ordinal
或StringComparison.OrdinalIgnoreCase
进行比较以获得更好的性能。 - 当比较语言无关紧要时(例如符号),使用非语言
StringComparison.Ordinal
或StringComparison.OrdinalIgnoreCase
值,而不是基于CultureInfo.InvariantCulture
的string操作。
最后:
- 在大多数情况下,不要使用基于
StringComparison.InvariantCulture
string操作 。 less数例外之一是,当你坚持语言有意义但文化不可知的数据。
另一个方便的差异(英语中重音不常见)是InvariantCulture比较首先比较整个string不区分大小写,然后如果必要(和请求)首先比较只在不同的字母之后进行区分。 (当然也可以做一个不区分大小写的比较,当然这并不能区分大小写。) 更正:重音字母被认为是同一个字母的另一个味道,首先比较string忽略重音,然后解释它们如果一般字母都匹配(就像不同的情况一样,除非在不区分大小写的情况下最终忽略不计)。 这会将相同词语的重音版本彼此靠近而不是在第一个重音差异处完全分开。 这是您通常在字典中find的sorting顺序,大写字母出现在小写字母旁边,重音字母靠近相应的非重音字母。
一个序数比较严格的数字字符值,停止在第一个差异。 这种大写字母与小写字母完全分开(大写字母与大写字母可能是分开的),所以大写的字母根本不会在小写字母之间出现。
InvariantCulture也认为大写字母大于小写字母,而Ordinal认为大写字母小于小写字母(在计算机使用小写字母之前,原来的ASCII保留,大写字母先被分配,因此其值小于小写字母稍后添加)。
例如,通过Ordinal:“0”<“9”<“A”<“Ab”<“Z”<“a”<“aB”<“ab”<“z”<“ “á”<“áb”
并且通过InvariantCulture:“0”<“9”<“a”<“a”“ab”<“aB”<“Ab”<“áb”<“bb”<“z “<”Z“
不变是语言上适当的比较types。
序数是一种二元types的比较。 (更快)
见http://www.siao2.com/2004/12/29/344136.aspx
虽然问题是关于平等 ,为了快速的视觉参考,这里的一些string顺序排列使用一些文化,说明了一些特质。
Ordinal 0 9 A Ab a aB aa ab ss Ä Äb ß ä äb ぁ あ ァ ア 亜 A IgnoreCase 0 9 a A aa ab Ab aB ss ä Ä äb Äb ß ぁ あ ァ ア 亜 A -------------------------------------------------------------------- InvariantCulture 0 9 a A A ä Ä aa ab aB Ab äb Äb ss ß ァ ぁ ア あ 亜IgnoreCase 0 9 A a A Ä ä aa Ab aB ab Äb äb ß ss ァ ぁ ア あ 亜-------------------------------------------------------------------- da-DK 0 9 a A A ab aB Ab ss ß ä Ä äb Äb aa ァ ぁ ア あ 亜IgnoreCase 0 9 A a A Ab aB ab ß ss Ä ä Äb äb aa ァ ぁ ア あ 亜-------------------------------------------------------------------- de-DE 0 9 a A A ä Ä aa ab aB Ab äb Äb ß ss ァ ぁ ア あ 亜IgnoreCase 0 9 A a A Ä ä aa Ab aB ab Äb äb ss ß ァ ぁ ア あ 亜-------------------------------------------------------------------- en-US 0 9 a A A ä Ä aa ab aB Ab äb Äb ß ss ァ ぁ ア あ 亜IgnoreCase 0 9 A a A Ä ä aa Ab aB ab Äb äb ss ß ァ ぁ ア あ 亜-------------------------------------------------------------------- ja-JP 0 9 a A A ä Ä aa ab aB Ab äb Äb ß ss ァ ぁ ア あ 亜IgnoreCase 0 9 A a A Ä ä aa Ab aB ab Äb äb ss ß ァ ぁ ア あ 亜
观察:
-
de-DE
,ja-JP
和en-US
按照相同的方式sorting -
Invariant
只能分类ss
和ß
不同于上述三种文化 -
da-DK
sorting完全不同 -
IgnoreCase
标志对所有取样文化都很重要
用于生成上表的代码:
var l = new List<string> { "0", "9", "A", "Ab", "a", "aB", "aa", "ab", "ss", "ß", "Ä", "Äb", "ä", "äb", "あ", "ぁ", "ア", "ァ", "A", "亜" }; 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)); }
这里是一个例子,其中使用InvariantCultureIgnoreCase和OrdinalIgnoreCase的string相等比较不会给出相同的结果:
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。
总是尝试在接受它作为重载的string方法中使用InvariantCulture。 通过使用InvariantCulture你是安全的。 许多.NET程序员可能不会使用此function,但如果您的软件将被不同的文化使用,InvariantCulture是一个非常方便的function。
- 可以在.Net 4.0中使用Tuple的实际示例?
- 如何获得与System.Net.DNS DNS名称的mxlogging?
- CryptographicException在试图导出X509私钥的RSAParameters时“密钥无法在指定状态下使用”
- 从HttpWebRequest和HttpWebResponse获取Http状态代码(200,301,404等)
- 为什么没有Windows.Forms.TreeView的SelectedNodeChanged事件?
- 返回声明应该在锁内还是外?
- 什么是一些好的.NET分析器?
- 为什么.NET调用.NET?
- 如何在一个generics扩展方法中使用string列名在IQueryable上应用OrderBy?