首页 > 解决方案 > 字符串比较器意外结果 - 错误排序?

问题描述

考虑以下两个字符串元素的列表,使用 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中复制了这个

但是,在https://try.dot.net/中复制相同的代码会给出预期的结果,无论是否a包含两个字符串末尾的字母。

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

编辑:使用相同的结果正在发生list.Sort(StringComparer.InvariantCulture);

谁能解释为什么会这样?

标签: c#stringlinqsorting

解决方案


默认的 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。哪个:

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


推荐阅读