我在代码中发现了一个由String.CompareTo和二进制搜索产生的错误,因为我的自定义IComparer(用于包装类型)使用String.Compare(x, y, StringComparison.Ordinal)
。
这是因为用于构建要搜索的数组的items.OrderBy(i => i.Name)
(其中Name是字符串类型)使用字符串对象本身作为IComparable,并且具有不同的规则:
比较使用当前文化来获得特定文化的信息,如大小写规则和单个字符的字母顺序。例如,区域性可以指定将某些字符组合视为单个字符,或者以特定方式比较大小写字符,或者指定字符的排序顺序取决于其前面或后面的字符。
例如,{A,b,C}使用Default String Compare按OrderBy排序为[A, b, C]
,但根据Ordinal比较应为[b, A, C]
-因为不是,所以二进制搜索失败。
现在,随着"上下文"的排除,
对具有与String.Compare(.., StringComparison.Ordinal)
相同的字符串属性的对象进行排序的最简单方法是什么(例如,不为字符串实现自定义IComparer)?
编辑:我[刚刚意识到我]可以,也可能应该,只使用OrderBy(x => x, theSameComparer)
——但如果这不可能,OrderBy怎么能得到同样的结果呢?
有一个预构建的StringComparer
应用StringComparison.Ordinal
,即StringComparer.Ordinal
:
items.OrderBy(i => i.Name, StringComparer.Ordinal)
您应该能够将StringComparer.Ordinal
直接添加到OrderBy
中。
string[] content = { "A", "b", "C", "d", "AB", "Ab" };
var ordered = content.OrderBy(o => o, StringComparer.Ordinal);
然后,一旦您迭代ordered
,您将收到以下输出:
// Output: A AB Ab C b d
我相信那是你追求的。
值得一提的是,它不仅可以在Linq
:中使用,还可以用于Array
和List
排序
string[] content = { "A", "b", "C", "d", "AB", "Ab" };
Array.Sort(content);
//output: A,Ab,AB,b,C,d
Array.Sort(content, StringComparer.Ordinal);
//output: A,AB,Ab,C,b,d
var list = new List<string>{ "A", "b", "C", "d", "AB", "Ab" };
list.Sort(StringComparer.Ordinal);
//output: the same as array.srot and linq with Ordinal comparer