首页 文章

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

提问于
浏览
459

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

9 回答

  • 26

    InvariantCulture

    使用"standard"字符排序集(a,b,c,...等) . 这与某些特定区域设置形成对比,这些区域设置可能按不同顺序对字符进行排序('a-with-acute'可能在'a'之后'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) .

  • 3

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

    var s1 = "Strasse";
            var s2 = "Straße";
    
            s1.Equals(s2, StringComparison.Ordinal);           //false
    
            s1.Equals(s2, StringComparison.InvariantCulture);  //true
    

    随着 InvariantCulture ,ß角色扩展为ss .

  • 261

    指向Best Practices for Using Strings in the .NET Framework

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

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

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

    最后:

    • Do not use string operations based on StringComparison.InvariantCulture in most cases . 少数例外情况之一是当你坚持语言上有意义但文化上不可知的数据时 .
  • 77

    另一个方便的区别(在英语中,重音不常见)是InvariantCulture比较首先按不区分大小写比较整个字符串,然后在必要时(和请求)在首先仅对不同的字母进行比较之后进行区分 . (当然,您也可以进行不区分大小写的比较,但不会因情况而区分 . ) Corrected: 重音字母被认为是相同字母的另一种字母,字符串首先忽略重音,然后对其进行比较 . 一般字母全部匹配(与不同情况一样,除非在不区分大小写的比较中最终被忽略) . 这将其他相同单词的重音版本分组,而不是在第一个重音差异处完全分开 . 这是您通常在字典中找到的排序顺序,大写单词出现在它们的小写等价物旁边,重音字母靠近相应的非重音字母 .

    序数比较严格比较数字字符值,停在第一个差异 . 这种大写字母与小写字母(以及可能与那些字母分开的重音字母)完全分开,因此大写字母在其小写等价物附近排序 .

    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"

  • -7

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

  • 1

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

    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-DEja-JPen-US 以相同的方式排序

    • Invariant 仅对 ssß 进行排序,与上述三种文化不同

    • da-DK 排序完全不同

    • 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));
    }
    
  • 26

    下面是一个示例,其中使用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 .

  • 54

    无需使用花哨的unicode char exmaples来显示差异 . 这是我今天发现的一个简单的例子,它令人惊讶,仅由ASCII字符组成 .

    根据ASCII表, 0 (0x48)在通常比较时小于 _ (0x95) . InvariantCulture会说相反(下面的PowerShell代码):

    PS> [System.StringComparer]::Ordinal.Compare("_", "0")
    47
    PS> [System.StringComparer]::InvariantCulture.Compare("_", "0")
    -1
    
  • 182

    总是尝试在那些接受它作为重载的字符串方法中使用InvariantCulture . 通过使用InvariantCulture,您可以放心使用 . 许多.NET程序员可能不会使用此功能,但如果您的软件将被不同的文化使用,InvariantCulture是一个非常方便的功能 .

相关问题