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

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

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

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


当前回答

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

将函数编写为通用函数:

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”方式,但它可能会给你一个如何以通用方式实现的线索

其他回答

//Get data from database, then sort list by staff name:

List<StaffMember> staffList = staffHandler.GetStaffMembers();

var sortedList = from staffmember in staffList
                 orderby staffmember.Name ascending
                 select staffmember;

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

将函数编写为通用函数:

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”方式,但它可能会给你一个如何以通用方式实现的线索

经典的面向对象解决方案

首先,我必须向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的情况下,正如你所说:

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()

var obj = db.Items.Where...

var orderBYItemId = obj.OrderByDescending(c => Convert.ToInt32(c.ID));