我有一个名为Order的类,它具有OrderId、OrderDate、Quantity和Total等财产。我有这个订单类的列表:

List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders

我想根据Order对象的一个属性对列表进行排序;例如通过订单日期或订单id。

如何在C#中执行此操作?


当前回答

使用LiNQ OrderBy

List<Order> objListOrder=new List<Order> ();
    objListOrder=GetOrderList().OrderBy(o=>o.orderid).ToList();

其他回答

您可以对财产选择做一些更通用的操作,但也可以对您选择的类型进行特定操作,例如“订单”:

将函数编写为通用函数:

public List<Order> GetOrderList<T>(IEnumerable<Order> orders, Func<Order, T> propertySelector)
        {
            return (from order in orders
                    orderby propertySelector(order)
                    select order).ToList();
        } 

然后这样使用:

var ordersOrderedByDate = GetOrderList(orders, x => x.OrderDate);

您可以更加通用,并为您想要订购的产品定义一个开放类型:

public List<T> OrderBy<T,P>(IEnumerable<T> collection, Func<T,P> propertySelector)
        {
            return (from item in collection
                    orderby propertySelector(item)
                    select item).ToList();
        } 

并以相同的方式使用:

var ordersOrderedByDate = OrderBy(orders, x => x.OrderDate);

这是一种愚蠢而不必要的复杂LINQ风格的“OrderBy”方式,但它可能会给你一个如何以通用方式实现的线索

订购列表的最简单方法是使用OrderBy

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

如果要按多个列排序,如以下SQL查询。

ORDER BY OrderDate, OrderId

要实现这一点,您可以像下面这样使用ThenBy。

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

从性能的角度来看,最好使用排序列表,以便在将数据添加到结果中时对其进行排序。其他方法至少需要对数据进行一次额外的迭代,并且大多数方法都会创建数据的副本,这样不仅会影响性能,还会影响内存使用。数百个元素可能不会有问题,但数千个元素可能会有问题,特别是在许多并发请求可能同时进行排序的服务中。查看System.Collections.Generic命名空间,然后选择一个带有排序的类,而不是List。

尽可能避免使用反射的通用实现,这也会导致性能问题。

经典的面向对象解决方案

首先,我必须向LINQ的伟大致敬。。。。现在我们已经把它排除在外了

JimmyHoffa答案的变体。使用泛型时,CompareTo参数变为类型安全。

public class Order : IComparable<Order> {

    public int CompareTo( Order that ) {
        if ( that == null ) return 1;
        if ( this.OrderDate > that.OrderDate) return 1;
        if ( this.OrderDate < that.OrderDate) return -1;
        return 0;
    }
}

// in the client code
// assume myOrders is a populated List<Order>
myOrders.Sort(); 

当然,这个默认的可排序性是可重用的。也就是说,每个客户端不必冗余地重新写入排序逻辑。交换“1”和“-1”(或逻辑运算符,由您选择)可反转排序顺序。

使用LINQ

objListOrder = GetOrderList()
                   .OrderBy(o => o.OrderDate)
                   .ToList();

objListOrder = GetOrderList()
                   .OrderBy(o => o.OrderId)
                   .ToList();