如何在C#中高效按多属性排序自定义对象列表(先升后降)?
C# 多属性排序:先按PropertyA升序,再按PropertyB降序
方法一:LINQ 链式排序(简洁直观)
LINQ的OrderBy(升序)结合ThenByDescending(次要条件降序)可以直接实现多属性排序,你之前可能没用到ThenBy系列方法——它专门用来指定后续排序规则。
代码示例:
// 自定义对象类 public class MyObject { public int PropertyA { get; set; } public string PropertyB { get; set; } // 其他类型(如int、DateTime)逻辑一致 } // 排序实现 List<MyObject> myList = new List<MyObject> { new MyObject { PropertyA = 2, PropertyB = "B" }, new MyObject { PropertyA = 1, PropertyB = "C" }, new MyObject { PropertyA = 2, PropertyB = "A" } }; // 先按PropertyA升序,再按PropertyB降序 var sortedList = myList.OrderBy(obj => obj.PropertyA) .ThenByDescending(obj => obj.PropertyB) .ToList();
- 此方法返回新的排序后列表,原列表保持不变
- 代码可读性强,大多数场景下性能足够高效
方法二:List.Sort 原地排序(内存更高效)
如果需要直接修改原列表、避免额外内存开销,可以用List.Sort结合自定义比较逻辑,有两种实现方式:
方式1:使用 Comparison 委托(快速实现)
myList.Sort((x, y) => { // 先比较PropertyA(升序) int aCompare = x.PropertyA.CompareTo(y.PropertyA); if (aCompare != 0) return aCompare; // PropertyA相等时,比较PropertyB(降序,通过反转比较对象实现) return y.PropertyB.CompareTo(x.PropertyB); });
- 直接在原列表上排序,无需额外内存存储新列表
- 逻辑清晰:先处理首要排序条件,相等时再判断次要条件
方式2:实现 IComparer 接口(适合复用场景)
如果该排序逻辑需要在多处复用,可封装为独立比较器:
public class MyObjectComparer : IComparer<MyObject> { public int Compare(MyObject x, MyObject y) { if (x == null || y == null) return 0; // 可根据需求自定义null值处理逻辑 int aCompare = x.PropertyA.CompareTo(y.PropertyA); if (aCompare != 0) return aCompare; return y.PropertyB.CompareTo(x.PropertyB); } } // 使用方式 myList.Sort(new MyObjectComparer());
- 比较器可复用,适合复杂或频繁使用的排序规则
- 可在
Compare方法中添加边界情况处理(如null值、自定义类型比较)
关键注意事项
- 确保排序属性的类型实现了
IComparable<T>接口(int、string、DateTime等默认已实现);如果是自定义类型,需自行实现该接口 - LINQ方法适合不希望修改原数据的场景,
List.Sort适合追求内存效率的场景
内容的提问来源于stack exchange,提问作者Jonathan Fleury-Smith
相关产品推荐
相关产品推荐

