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

时间:2012-02-14 20:21:38

标签: c# .net linq

假设我们有一个实现MyDataIComparable<MyData>接口的IComparable类。然后我们有一个包含许多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;

当LINQ对list中的元素进行排序时,它是否使用IComparable类中MyData接口的实现?

如果答案是,最好将排序条件封装在类MyData中(通过实现上述接口)或在LINQ查询中指定条件(不使用{ {1}}实现这些接口)?这两种选择的优缺点是什么?

3 个答案:

答案 0 :(得分:5)

Enumerable.OrderBy“使用默认比较器Default”比较密钥,而后者将使用您的IComparable<T>实施。

  

如果答案是肯定的,最好将排序条件封装在MyData类中(通过实现上述接口)还是在LINQ查询中指定条件(没有实现这些接口的MyData)?这两种选择的优缺点是什么?

首先,答案是肯定的。

这两种方法都有优势。

实施IComparable<T>表明该类型具有自然顺序。如果是这样,我喜欢实现这个接口。就LINQ而言,主要的专业是你简化你的LINQ查询(一点点)。但是,我的主要专业人员更倾向于对该给定类型的“自然”订单的建议,这反过来又增加了API的清晰度。

在LINQ查询中指定标准的主要原因是灵活性。这允许您按任意数量的标准排序 - 不限制自己使用类型本身定义的给定排序。如果没有类型的“自然”排序顺序(即:它不代表某个“数量”本身或类似的东西),那么我个人会使用这种方法。

答案 1 :(得分:3)

OrderBy扩展方法采用Func<>委托 - 这是用于选择用于排序的项目。其中一个重载需要IComparer个实例用于比较 - 那些不使用Default比较器的实例。

看看EduLinq-- Jon Skeet对LINQ的教育重新实现,看看如何做到这一点 - here is the OrderBy post

答案 2 :(得分:2)

在这种情况下,它使用Enumerable.OrderBy,它使用Default Comparer:

  

此方法使用默认比较器Default。

比较键      

此方法执行稳定排序;也就是说,如果两个键   元素相等,元素的顺序得以保留。在   相反,不稳定的排序不会保留元素的顺序   具有相同的密钥。

可能需要注意的是,如果您使用的是Linq2SQL或其他一些LINQ提供程序,则情况不一定如此。这只适用,因为这是IEnumerable实现(Linq2Objects)。