字母顺序从左到右不比较?

Tim*_*ter 5 .net c# sorting string .net-4.0

我认为.NET字符串按字母顺序进行比较,并且从左到右进行比较.

string[] strings = { "-1", "1", "1Foo", "-1Foo" };
Array.Sort(strings);
Console.WriteLine(string.Join(",", strings));
Run Code Online (Sandbox Code Playgroud)

我期待这个(或者两者都是开头的减号):

1,1Foo,-1,-1Foo
Run Code Online (Sandbox Code Playgroud)

但结果是:

1,-1,1Foo,-1Foo
Run Code Online (Sandbox Code Playgroud)

它似乎是一种混合,要么忽略减号,要么比较多个字符,即使第一个字符已经不同.

编辑:我现在已经过测试OrdinalIgnoreCase,我得到了预期的订单:

Array.Sort(strings, StringComparer.OrdinalIgnoreCase);
Run Code Online (Sandbox Code Playgroud)

但即使我使用InvariantCultureIgnoreCase 我得到意想不到的顺序.

Noc*_*tis 2

乔恩·斯基特来救援

具体来说:

.NET Framework 使用三种不同的排序方式:单词排序、字符串排序和序数排序。词排序对字符串执行区域性敏感的比较。某些非字母数字字符可能分配有特殊的权重。例如,连字符(“-”)可能分配有非常小的权重,以便“coop”和“co-op”在排序列表中彼此相邻出现。字符串排序与单词排序类似,只是没有特殊情况。因此,所有非字母数字符号都位于所有字母数字字符之前。序数排序根据字符串每个元素的 Unicode 值来比较字符串。

但添加 StringComparer.Ordinal 使其行为如您所愿:

string[] strings = { "-1", "1", "10", "-10", "a", "ba","-a" };      
Array.Sort(strings,StringComparer.Ordinal );
Console.WriteLine(string.Join(",", strings));
// prints: -1,-10,-a,1,10,a,ba
Run Code Online (Sandbox Code Playgroud)

编辑
关于序数,引用自MSDN CompareOptions 枚举

序号 指示字符串比较必须使用字符串的连续 Unicode UTF-16 编码值(逐个代码单元比较),从而实现快速比较,但比较不区分区域性。如果 XXXX16 小于 YYYY16,则以代码单元 XXXX16 开头的字符串位于以 YYYY16 开头的字符串之前。该值不能与其他 CompareOptions 值结合使用,必须单独使用。

如果你想要 2 个字符串的序数,似乎你也有String.CompareOrdinal 。

这是另一个有趣的注释:

如果可能,应用程序应使用接受 CompareOptions 值的字符串比较方法来指定预期的比较类型。作为一般规则,面向用户的比较最好通过使用语言选项(使用当前区域性)来进行,而安全比较应指定 Ordinal 或 OrdinalIgnoreCase。

我想我们人类在处理字符串时期望序数:)