LINQ OrderBy字符串排序大小写顺序异常及排序规则咨询
字符串排序问题解答
问题代码
string str1 = "M"; // <---77 string str2 = "m"; // <---109 var list = new List<string>() {str1, str2}; list = list.OrderBy(a=>a).ToList();
疑问
尽管小写m的ASCII码更大,但排序后m却排在M之前,请问这是为什么?另外,LINQ排序使用的是哪种比较方式?如何修改该比较方式?
原因分析
默认的字符串排序不是直接对比ASCII码值,而是采用当前系统文化对应的Unicode排序规则。在多数默认文化(如英语)中,Unicode排序会将小写字母的排序优先级置于对应大写字母之前,同时大小写差异的权重低于字母本身的差异,所以即使m的ASCII码数值更大,排序后仍会出现在M前面。
LINQ默认比较方式
LINQ的OrderBy方法默认使用Comparer<string>.Default,对于字符串类型,它等价于StringComparer.CurrentCulture——即基于当前线程的文化设置进行文化敏感的字符串比较,会遵循该文化下的语言排序习惯,而非单纯的二进制码值对比。
修改比较方式的方案
根据不同需求,可以指定不同的字符串比较器:
- 基于ASCII/二进制码值排序(严格按字符的Unicode码值对比,此时
M的77小于m的109,排序后M在前):list = list.OrderBy(a => a, StringComparer.Ordinal).ToList(); - 不区分大小写的文化敏感排序:
list = list.OrderBy(a => a, StringComparer.CurrentCultureIgnoreCase).ToList(); - 不区分大小写的二进制排序:
list = list.OrderBy(a => a, StringComparer.OrdinalIgnoreCase).ToList(); - 指定特定文化的排序(比如固定使用英语文化,不受系统当前文化影响):
var enCulture = new CultureInfo("en-US"); list = list.OrderBy(a => a, StringComparer.Create(enCulture, false)).ToList();
内容的提问来源于stack exchange,提问作者DooDoo
相关产品推荐
相关产品推荐

