请考虑此代码:
string str1 = "M"; // <---77
string str2 = "m"; // <---109
var list = new List<string>() {str1, str2};
list = list.OrderBy(a=>a).ToList();
问题是尽管
m
有更大的ascii代码,但它却在M
之前。为什么会发生在这里?
LINQ 使用什么类型的比较进行排序以及如何更改它?
如果未指定比较器,
OrderBy
将使用Comparer<T>.Default
获取比较器。最终,这似乎解决了 GenericComparer<T>
,它使用 string
的 CompareTo
方法。如果您想深入了解代码,可以从here开始查看。
StringComparer.InvariantCulture
的文档中的内容,似乎 m
在 M
之前是“语言相关”顺序,所以我假设其他文化敏感的英语比较器也假设相同订购。
至于如何按照您想要的方式排序,您可以为
OrderBy
方法指定一个比较器(内置或自定义)。例如:list.OrderBy(a => a, StringComparer.InvariantCulture)
(但可能不是这个比较器)。
我不知道有哪个特定的比较器可以按照您想要的方式对其进行排序,因此您可能需要创建一个类似于这样的自定义比较器:
public class CustomStringComparer : IComparer<string>
{
private static readonly CustomStringComparer _instance = new CustomStringComparer();
public static CustomStringComparer Instance => _instance;
private CustomStringComparer() { }
public int Compare (string x, string y)
{
if (string.Equals(x, y))
{
return 0;
}
int minLength = Math.Min(x.Length, y.Length);
for (int i = 0; i < minLength; ++i)
{
var compareResult = ((int)x[i]).CompareTo(y[i]);
if (compareResult != 0)
{
return compareResult;
}
}
return 0;
}
}
这只是一个基于您想要比较 ASCII 代码的隐含愿望的示例。我预计它不能很好地处理很多情况,因此如果您希望它完全按照您的需要进行操作,您可能需要对其进行更改。
用途:
list = list.OrderBy(a => a, CustomStringComparer.Instance).ToList();