【发布时间】:2011-04-10 11:31:15
【问题描述】:
我看到一些使用 CaseInsensitiveComparer.DefaultInvariant 的非常奇怪的排序行为。以连字符“-”开头的单词最终会被排序,就好像连字符不存在一样,而不是像其他标点符号那样被排序在实际字母前面。
所以给定 { "hello", ".net", "-less"} 我最终得到 {".net", "hello", "-less" } 而不是预期的 {"-less", " .net”,“你好”}。
或者,用测试用例来表述:
[TestMethod]
public void TestMethod1()
{
var rg = new String[] {
"x", "z", "y", "-less", ".net", "- more", "a", "b"
};
Array.Sort(rg, CaseInsensitiveComparer.DefaultInvariant);
Assert.AreEqual(
"- more,-less,.net,a,b,x,y,z",
String.Join(",", rg)
);
}
... 像这样失败:
Assert.AreEqual failed.
Expected:<- more,-less,.net,a,b,x,y,z>.
Actual: <- more,.net,a,b,-less,x,y,z>.
有什么想法吗?
编辑:
看起来,默认情况下,.NET 在对字符串进行排序时会做一些花哨的事情,这会导致前导连字符被排序到奇怪的位置,以便合作和合作排序在一起。因此,如果您希望前导连字符以其他标点符号结尾并以其他标点符号开头,您必须告诉它不要:
Array.Sort(rg, (a, b) => String.CompareOrdinal(a, b));
【问题讨论】:
-
不加空格可能被认为类似于负号
-
如果每个问题都可以表示为一个单元测试。
-
我不知道点 '.',但看起来 StringComparer.InvariantCulture 在进行比较之前只是吃掉了所有的破折号 '-'。