我认为.NET字符串按字母顺序进行比较,并且从左到右进行比较。
string[] strings = { "-1", "1", "1Foo", "-1Foo" };
Array.Sort(strings);
Console.WriteLine(string.Join(",", strings));
我期待这一点(或者首先是开头的减号):
1,1Foo,-1,-1Foo
但结果是:
1,-1,1Foo,-1Foo
它似乎是一种混合,要么忽略减号,要么比较多个字符,即使第一个字符已经不同。
修改:我现在已经测试OrdinalIgnoreCase
了,我得到了预期的订单:
Array.Sort(strings, StringComparer.OrdinalIgnoreCase);
但即使我使用InvariantCultureIgnoreCase
,我也会收到意外的订单。
答案 0 :(得分:2)
String.CompareTo方法文档中有一个小注释:
来电者注意事项:
字符集包括可忽略的字符。该 CompareTo(String)方法不考虑这样的字符 进行文化敏感的比较。例如,如果以下 代码在.NET Framework 4或更高版本上运行,比较“动物” 用“ani-mal”(使用软连字符,或U + 00AD)表示两者 字符串是等价的。
然后稍后陈述:
要识别字符串比较中的可忽略字符,请调用 CompareOrdinal(String,String)方法。
这两个陈述似乎与您所看到的结果一致。
答案 1 :(得分:2)
Jon Skeet拯救here
具体做法是:
.NET Framework使用三种不同的排序方式:单词排序, 字符串排序和序数排序。单词排序执行文化敏感 字符串的比较。某些非字母数字字符可能有 分配给他们的特殊权重。例如,连字符(“ - ”)可能 分配给它的重量非常小,以便“合作”和“合作” 在排序列表中彼此相邻。字符串排序类似于 单词排序,除了没有特殊情况。所以,一切 非字母数字符号位于所有字母数字字符之前。 序数排序根据每个字符串的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
修改强>:
关于Ordinal,引自MSDN CompareOptions Enumeration
Ordinal 表示字符串比较必须使用连续 Unicode UTF-16编码的字符串值(代码单位的代码单位) 比较),导致快速比较,但一个 文化不敏感。以代码单元XXXX16开头的字符串出现 在以YYYY16开头的字符串之前,如果XXXX16小于YYYY16。 此值不能与其他CompareOptions值组合使用 必须单独使用。
如果你想要2个字符串的序数,你似乎也有String.CompareOrdinal。
这是另一个感兴趣的注意事项:
如果可能,应用程序应使用字符串比较方法 接受CompareOptions值以指定比较类型 预期。作为一般规则,最佳服务是面向用户的比较 通过使用语言选项(使用当前的文化),同时 安全性比较应指定Ordinal或OrdinalIgnoreCase。
我猜我们人类在处理字符串时会期望序数:)