OrderBy 返回新序列不修改原列表,需赋值或转集合;null 默认排最前,可用空合并或自定义比较器调整;性能不如Sort(),大数据量优先用Sort();多级排序用ThenBy/ThenByDescending,避免重复OrderBy覆盖。

OrderBy 会创建新列表,原 List 不变
很多人调用 OrderBy 后发现原 list 没排序,是因为它返回的是 IOrderedEnumerable<t></t>,不是就地修改。你得显式赋值回去,或者转成新集合。
- 错误写法:
list.OrderBy(x => x.Name);—— 结果被丢弃,list依然乱序 - 正确写法:
list = list.OrderBy(x => x.Name).ToList(); - 如果只是临时遍历,不改原数据:
foreach (var item in list.OrderBy(x => x.Id)) { ... }
OrderBy 默认按升序,但 null 值排最前(可能不符合预期)
当排序字段是引用类型(比如 string 或自定义类属性),且含 null,OrderBy 默认把 null 当最小值处理,排在升序最前面。这在分页或 UI 展示时容易出视觉偏差。
- 想让
null排最后:用OrderBy(x => x.Name ?? "")(强制转空字符串),或更稳妥地用OrderBy(x => x.Name, StringComparer.Ordinal)配合自定义比较逻辑 - 对可空数值(如
int?):OrderBy(x => x.Age.GetValueOrDefault(int.MaxValue))把null当最大值塞末尾
OrderBy 性能比 Sort() 差,大数据量别无脑用
OrderBy 是 LINQ 查询,底层走的是稳定排序 + 迭代器 + 延迟执行,内存开销大;而 List<t>.Sort()</t> 是就地快排,没有额外分配。
- 10 万条以内,差别不明显;超 50 万条,
Sort()通常快 2–3 倍,GC 压力小得多 - 要用
Sort()升序:list.Sort((a, b) => string.Compare(a.Name, b.Name)); - 注意:
Sort()要求比较逻辑不能抛异常,比如两个null字符串直接a.Name.CompareTo(b.Name)会 NRE,得先判空
OrderBy 支持链式多级排序,但顺序不能反
升序后接降序得用 ThenByDescending,不是再写一遍 OrderByDescending —— 后者会覆盖前面的排序逻辑。
- 正确多级:
list.OrderBy(x => x.Type).ThenByDescending(x => x.CreatedAt) - 错误写法:
list.OrderBy(x => x.Type).OrderByDescending(x => x.CreatedAt)—— 第二个OrderByDescending重置了整个排序,Type就白排了 - 如果字段是值类型(如
int),直接用x.Id没问题;但引用类型建议加空安全,比如ThenBy(x => x.Tag?.Trim() ?? "")










