简体   繁体   English

LINQ如何按给定标准对项目进行排序?

[英]How does LINQ sort items by a given criteria?

Suppose we have a MyData class which implements the IComparable<MyData> and IComparable interfaces. 假设我们有一个MyData类,它实现了IComparable<MyData>IComparable接口。 Then we have a list containing many of MyData elements and a LINQ query to get a sorted list. 然后我们有一个包含许多MyData元素的列表和一个LINQ查询来获取一个排序列表。

public class MyData : IComparable<MyData>, IComparable
{
    ...

    public int CompareTo(MyData value)
    {
        // TODO
    }

    public int CompareTo(object value)
    {
        if (value == null)
            return 1;

        if (value.GetType() == typeof(MyData))
        {
            MyData rightValue = (MyData)value;
            return (this.CompareTo(rightValue));
        }
        else throw new ArgumentException("Object is not a " + typeof(MyData) + ".");
    }
}

// main method
List<MyData> list = new List<MyData>();
...
var items = from item in list
            orderby item descending
            select item;

When LINQ sorts the elements within the list , does it use the implementation of IComparable interface in the MyData class? 当LINQ对list的元素进行排序时,它是否使用MyData类中的IComparable接口的实现?

If the answer is yes , is it better to encapsulate the sort criteria in the class MyData (by implementing the above interfaces) or specify the criteria in a LINQ query (without MyData that implements these interfaces)? 如果答案是肯定的 ,是否最好将排序条件封装在MyData类中(通过实现上述接口)或在LINQ查询中指定条件(没有实现这些接口的MyData )? What are the pros and cons of these two choices? 这两种选择的优缺点是什么?

Enumerable.OrderBy "compares keys by using the default comparer Default ", which in turn will use your IComparable<T> implementation. Enumerable.OrderBy “使用默认比较器Default来比较键”,然后使用您的IComparable<T>实现。

If the answer is yes, is it better to encapsulate the sort criteria in the class MyData (by implementing the above interfaces) or specify the criteria in a LINQ query (without MyData that implements these interfaces)? 如果答案是肯定的,是否最好将排序条件封装在MyData类中(通过实现上述接口)或在LINQ查询中指定条件(没有实现这些接口的MyData)? What are the pros and cons of these two choices? 这两种选择的优缺点是什么?

So first, the answer is yes. 首先,答案是肯定的。

Both approaches have advantages. 两种方法都有优势。

Implementing IComparable<T> suggests that the type has a natural ordering. 实现IComparable<T>表明该类型具有自然顺序。 When this is true, I like implementing this interface. 如果是这样,我喜欢实现这个接口。 The main pro, in terms of LINQ, is that you simplify your LINQ queries (a bit). 就LINQ而言,主要的专业是你简化你的LINQ查询(一点点)。 However, my main pro is more the suggestion of a "natural" order for that given type, which, in turn, adds to the clarity of your API. 但是,我的主要专业人员更倾向于对该给定类型的“自然”顺序的建议,这反过来又增加了API的清晰度。

The main pro of specifying the criteria in the LINQ query itself is flexibility. 在LINQ查询中指定标准的主要原因是灵活性。 This allows you to sort by any number of criteria - not restricting yourself to a given sort defined in the type itself. 这允许您按任意数量的标准排序 - 不限制自己使用类型本身定义的给定排序。 If there isn't a "natural" sorting order for the type (ie: it's not representing something that is a "quantity" all on its own or similar), then I'd personally use this method. 如果没有类型的“自然”排序顺序(即:它不代表某个“数量”本身或类似的东西),那么我个人使用这种方法。

The OrderBy extension methods take Func<> delegate - this is what is used to select the item used for sorting. OrderBy扩展方法采用Func<>委托 - 这是用于选择用于排序的项目。 One of the overloads takes an IComparer instance to use for comparisons - the ones that don't use the Default comparer. 其中一个重载需要IComparer实例用于比较 - 那些不使用Default比较器的实例。

Take a look at EduLinq - an educational re-implementation of LINQ by Jon Skeet to see how this is done - here is the OrderBy post . 看看EduLinq-- Jon Skeet对LINQ的教育重新实现,看看这是如何完成的 - 这是OrderBy帖子

In this case it uses Enumerable.OrderBy , which uses the Default Comparer: 在这种情况下,它使用Enumerable.OrderBy ,它使用Default Comparer:

This method compares keys by using the default comparer Default. 此方法使用默认比较器Default来比较键。

This method performs a stable sort; 该方法执行稳定的排序; that is, if the keys of two elements are equal, the order of the elements is preserved. 也就是说,如果两个元素的键相等,则保留元素的顺序。 In contrast, an unstable sort does not preserve the order of elements that have the same key. 相反,不稳定的排序不会保留具有相同键的元素的顺序。

It is probably important to note that were you using Linq2SQL or some other LINQ provider, this is not necessarily the case. 可能需要注意的是,如果您使用的是Linq2SQL或其他LINQ提供程序,则情况不一定如此。 This only holds true because this is the IEnumerable implementation (Linq2Objects). 这只适用,因为这是IEnumerable实现(Linq2Objects)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM