字符串比较器意外的结果-错误的顺序?

时间:2019-01-21 11:32:42

标签: c# string linq sorting

考虑以下两个字符串元素的列表,使用Sort()对其进行排序或使用linq进行排序。OrderBy()给出了意外的结果,a.1.10-a-是新排序的列表中的第一个元素。

var list = new List<string> 
    {
        "a.1.1-a-",  
        "a.1.10-a-", 
    };
    list.Sort();
    foreach(var l in list)
        Console.WriteLine(l);
    foreach(var l in list.OrderBy(x=>x))
        Console.WriteLine(l);

实际结果:

a.1.10-a-
a.1.1-a-
------
a.1.10-a-
a.1.1-a-

但是,从每个元素中删除字母a时,输出将更改为:

a.1.1--
a.1.10--
------
a.1.1--
a.1.10--

我已在https://dotnetfiddle.net/NBF3Pf

中复制了此内容

但是,在两个字符串的末尾加上和不包括字母a的情况下,在https://try.dot.net/中复制相同的代码将获得预期的结果。

我尝试将每个字符串转换为char列表,​​然后转换为int列表。这两个列表是相同的,直到0的ASCII码为48和-的ASCII码为45。 48大于45,但是排序仍然将元素a.1.10-a-放在第一位。

编辑:使用list.Sort(StringComparer.InvariantCulture);

会发生相同的结果

谁能解释为什么会这样?

1 个答案:

答案 0 :(得分:0)

默认的StringComparer取决于您当前的区域性,因此可以在不同的计算机上给出不同的结果。尝试明确指定区域性以获得一致的结果:

    list.Sort(StringComparer.InvariantCulture);
    foreach(var l in list)
        Console.WriteLine(l);
    Console.WriteLine();

    foreach(var aa in list.OrderBy(x=>x, StringComparer.InvariantCulture))
        Console.WriteLine(aa);

您可以根据需要的结果考虑使用StringComparer.Ordinal。我怀疑您当前的文化可能正在使用CultureInfo.StringSort

  

表示字符串比较必须使用字符串排序算法。在字符串形式中,连字符和撇号以及其他非字母数字符号位于字母数字字符之前