如何按对象属性对List<T>进行排序

如何按对象属性对List进行排序

技术背景

在C#开发中,经常会遇到需要对List<T>集合中的对象按照其某个属性进行排序的场景。例如,对订单列表按照订单日期排序,对员工列表按照员工姓名排序等。合理地对列表进行排序可以提高数据的可读性和处理效率。

实现步骤

使用LINQ的OrderBy方法

这是最简洁的方式,适用于需要创建一个新的排序序列的场景。

1
List<Order> SortedList = objListOrder.OrderBy(o => o.OrderDate).ToList();

使用Sort方法和Comparison<T>委托

如果需要对列表进行原地排序,可以使用Sort方法。

1
objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

在.NET 2.0中不使用LINQ排序

1
2
3
4
5
6
7
List<Order> objListOrder = GetOrderList();
objListOrder.Sort(
delegate(Order p1, Order p2)
{
return p1.OrderDate.CompareTo(p2.OrderDate);
}
);

按多个属性排序

可以在委托中实现按多个属性排序。

1
2
3
4
5
6
7
8
9
10
11
orderList.Sort(
delegate(Order p1, Order p2)
{
int compareDate = p1.Date.CompareTo(p2.Date);
if (compareDate == 0)
{
return p2.OrderID.CompareTo(p1.OrderID);
}
return compareDate;
}
);

实现IComparer接口

为了提高代码的复用性,建议实现IComparer接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MyOrderingClass : IComparer<Order>
{
public int Compare(Order x, Order y)
{
int compareDate = x.Date.CompareTo(y.Date);
if (compareDate == 0)
{
return x.OrderID.CompareTo(y.OrderID);
}
return compareDate;
}
}

IComparer<Order> comparer = new MyOrderingClass();
orderList.Sort(comparer);

使用ThenBy按多列排序

类似于SQL中的ORDER BY多个列。

1
List<Order> objListOrder = source.OrderBy(order => order.OrderDate).ThenBy(order => order.OrderId).ToList();

不使用LINQ实现排序

可以让对象实现IComparable接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Order : IComparable
{
public DateTime OrderDate { get; set; }
public int OrderId { get; set; }

public int CompareTo(object obj)
{
Order orderToCompare = obj as Order;
if (orderToCompare.OrderDate < OrderDate || orderToCompare.OrderId < OrderId)
{
return 1;
}
if (orderToCompare.OrderDate > OrderDate || orderToCompare.OrderId > OrderId)
{
return -1;
}

// The orders are equivalent.
return 0;
}
}

// 调用sort方法
orderList.Sort();

通用排序扩展方法

1
2
3
4
5
6
7
8
public static void Sort<T, U>(this List<T> list, Func<T, U> expression)
where U : IComparable<U>
{
list.Sort((x, y) => expression.Invoke(x).CompareTo(expression.Invoke(y)));
}

// 使用方法
myList.Sort(x => x.myProperty);

支持自定义比较器的扩展方法

1
2
3
4
5
public static void Sort<T, U>(this List<T> list, Func<T, U> expression, IComparer<U> comparer)
where U : IComparable<U>
{
list.Sort((x, y) => comparer.Compare(expression.Invoke(x), expression.Invoke(y)));
}

对可空类型排序

1
objListOrder.Sort((x, y) => x.YourNullableType.Value.CompareTo(y.YourNullableType.Value));

最佳实践

  • 优先使用LINQ的OrderBy方法,因为它简洁且易于理解。
  • 如果需要对列表进行原地排序,使用Sort方法和Comparison<T>委托或实现IComparer接口。
  • 对于按多个属性排序的场景,使用ThenBy方法或在委托中实现多属性比较。
  • 避免在性能敏感的场景中使用反射,因为反射会影响性能。

常见问题

  • 性能问题:在处理大量数据时,使用反射或创建多个列表副本可能会导致性能下降。建议使用排序的数据结构或避免不必要的复制操作。
  • 可空类型问题:对可空类型进行排序时,需要注意使用Value属性。
  • 排序顺序问题:如果需要降序排序,可以通过交换比较结果的正负来实现。例如,y.OrderDate.CompareTo(x.OrderDate)可以实现按日期降序排序。

如何按对象属性对List<T>进行排序
https://119291.xyz/posts/how-to-sort-a-list-t-by-a-property-in-the-object/
作者
ww
发布于
2025年5月28日
许可协议