[英]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.