C#中的字符串排序问题

Sat*_*tya 14 c# sorting string cultureinfo

我有这样的列表

    List<string> items = new List<string>();
    items.Add("-");
    items.Add(".");
    items.Add("a-");
    items.Add("a.");
    items.Add("a-a");
    items.Add("a.a");

    items.Sort();

    string output = string.Empty;
    foreach (string s in items)
    {
        output += s + Environment.NewLine;
    }

MessageBox.Show(output);
Run Code Online (Sandbox Code Playgroud)

输出回来了

-
.
a-
a.
a.a
a-a
Run Code Online (Sandbox Code Playgroud)

在哪里我期待结果为

-
.
a-
a.
a-a
a.a
Run Code Online (Sandbox Code Playgroud)

知道为什么"aa"不会出现在"aa"之前,其中"a-"出现在"a"之前.

Max*_*kin 17

我怀疑在最后一种情况下,由于文化特定的设置(可能是"破折号"而不是第一个字符串中的"减号")," - "会以不同的方式处理.MSDN警告:

比较使用当前文化来获取特定于文化的信息,例如套管规则和单个字符的字母顺序.例如,文化可以指定某些字符组合被视为单个字符,或者以特定方式比较大写和小写字符,或者字符的排序顺序取决于其前面或后面的字符.

另请参阅此MSDN页面:

.NET Framework使用三种不同的排序方式:单词排序,字符串排序和顺序排序.单词排序执行文化敏感的字符串比较.某些非字母数字字符可能会分配特殊权重; 例如,连字符(" - ")可能具有非常小的权重,因此"coop"和"co-op"在排序列表中彼此相邻.字符串排序类似于单词排序,除了没有特殊情况; 因此,所有非字母数字符号都在所有字母数字字符之前.序数排序根据字符串的每个元素的Unicode值比较字符串.

因此,连字符在默认排序模式下获得特殊处理,以使单词排序更"自然".

如果您专门打开它,您可以获得"正常"序数排序:

     Console.WriteLine(string.Compare("a.", "a-"));                  //1
     Console.WriteLine(string.Compare("a.a", "a-a"));                //-1

     Console.WriteLine(string.Compare("a.", "a-", StringComparison.Ordinal));    //1
     Console.WriteLine(string.Compare("a.a", "a-a", StringComparison.Ordinal));  //1
Run Code Online (Sandbox Code Playgroud)

要使用序数比较对原始集合进行排序,请使用:

     items.Sort(StringComparer.Ordinal);
Run Code Online (Sandbox Code Playgroud)


Jar*_*ver 5

如果您希望字符串排序基于实际字节值而不是当前文化定义的规则,则可以按序数排序:

items.Sort(StringComparer.Ordinal);

这将使结果在所有文化中保持一致(但它会产生在“9”之前出现的“14”的不直观的排序,这可能是也可能不是您正在寻找的)。