当前位置:  开发笔记 > 编程语言 > 正文

InvariantCulture和Ordinal字符串比较之间的区别

如何解决《InvariantCulture和Ordinal字符串比较之间的区别》经验,为你挑选了7个好方法。

比较c#中的两个字符串是否相等,InvariantCulture和Ordinal比较之间有什么区别?



1> JaredReising..:

InvariantCulture的

使用"标准"字符排序集(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).


我觉得这是有用的信息,但实际上并没有回答这个问题.在确定两个字符串的*Equality*时,是否有任何理由使用InvarintCulture而不是Ordinal?似乎InvariantCulture将用于*Sort*字符串,而Ordinal应该用于*Equality*检查(我们不关心重音 - a来自a之前或之后,它只是不同).虽然,我自己有点不确定这一点.
序数比较查看*代码点*,而不是字节.
序数要快得多
请参阅http://msdn.microsoft.com/en-us/library/ms230117%28v=vs.90%29.aspx并注意建议使用字符串规范化和序数比较.
已发布了良好的性能测试结果[C#String Comparision Tests](http://rhale78.wordpress.com/2011/05/16/string-equality-and-performance-in-c/),它告诉每个不同的性能字符串比较方法和他们的时间.
@Joey看到.NET对所有字符串使用相同的编码(UTF-16),代码点和字节之间的区别是什么?另外文档状态*"在方法调用中指定StringComparison.Ordinal或StringComparison.OrdinalIgnoreCase值表示忽略自然语言的特征的非语言比较.使用这些StringComparison值调用的方法基于简单的字符串操作决策字节比较"*http://msdn.microsoft.com/en-us/library/dd465121(v=vs.100).aspx
关于上面MPavlak的“不确定”评论(此时)有106个赞成票,这表明在相等性检查方面,序数和不变式之间没有区别,实际上是有区别的。即使是由于字符扩展而导致的相等性检查,它们也有所不同,这在同一线程的另一个答案中得到了证明:/sf/ask/17360801/

2> Ventsyslav R..:

例如,它确实很重要 - 有一种叫做角色扩展的东西

var s1 = "Strasse";
var s2 = "Straße";

s1.Equals(s2, StringComparison.Ordinal);           //false
s1.Equals(s2, StringComparison.InvariantCulture);  //true

随着InvariantCultureß角色扩展到ss.


这不太正确@Peter,你不能在德语中互换使用`ß`和`s`(我是母语人士).有些情况下两者都是合法的(但通常有一个是过时的/不推荐的),并且有些情况下只允许使用一种表格.
这个简单的例子清楚地说明了两种比较之间的区别.我想我现在正在接受这个.
对于那些不知道"ß"的人,应该注意到至少在德语中的"ß"等于双倍,来源:https://en.wikipedia.org/wiki/%C3%9F
不得不尝试一下:https://ideone.com/j8Dv这么酷!还有一点德语课.想知道ß和ss之间有什么区别...

3> Dariusz..:

指向在.NET Framework中使用字符串的最佳实践:

使用StringComparison.OrdinalStringComparison.OrdinalIgnoreCase进行比较作为与文化无关的字符串匹配的安全默认值.

使用比较StringComparison.OrdinalStringComparison.OrdinalIgnoreCase获得更好的性能.

基于比较在语言上无关的时间(例如,符号),使用非语言StringComparison.OrdinalStringComparison.OrdinalIgnoreCase值而不是字符串操作CultureInfo.InvariantCulture.

最后:

StringComparison.InvariantCulture在大多数情况下,不要使用基于字符串的操作.少数例外情况之一是当你坚持语言上有意义但文化上不可知的数据时.



4> Rob Parker..:

另一个方便的区别(在英语中,重音不常见)是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"



5> Eugene Beres..:

虽然问题是关于平等,但为了快速视觉参考,这里使用一些文化排序的一些字符串的顺序说明了那里的一些特质.

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-JPen-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));
}



6> DanH..:

不变量是一种语言上适当的比较类型.
序数是二元类型的比较.(更快)
参见http://www.siao2.com/2004/12/29/344136.aspx



7> 小智..:

这是一个示例,其中使用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。

推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有