在“使用C#4.0 LINQ To Objects”的第64页(Tony Magennis),他说LINQ的快速排序算法不稳定......
......虽然这可以简单地解决 将结果级联到ThenBy或 然后是ByDescending运营商。
咦?为什么将不稳定的分类级联到另一个分类会修复结果?事实上,我认为这是不可能的。原始订单一旦通过不稳定的排序,就会丢失。我在这里缺少什么?
答案 0 :(得分:7)
简单地说,他错了。 Linq OrderBy
et al。方法documented执行稳定排序:
此方法执行稳定排序;也就是说,如果两个元素的键相等,则保留元素的顺序。相反,不稳定的排序不会保留具有相同键的元素的顺序。
答案 1 :(得分:5)
不稳定排序意味着x.OrderBy(...).OrderBy(...)
次调用链只能根据最终标准进行可靠排序。 x.OrderBy(...).ThenBy(...)
在应用新排序顺序时显式捕获先前排序顺序的知识。我相信它通过调用IOrderedEnumerable<TElement>.CreateOrderedEnumerable<TKey>
来做到这一点,尽管我对此并不是100%肯定。
编辑:只是要明确,当我说,“捕获知识......”我并不是说第一个OrderBy执行排序,不知何故第二个知道它做了什么。请记住,OrderBy
会返回IOrderedEnumerable<T>
,在有人尝试使用这些元素之前,它根本不会执行任何工作。在这种情况下,它永远不会执行排序,因为ThenBy
使用OrderBy
的排序方式的知识,构建了一个全新的排序器,它将两个排序顺序应用于预期的方式,只需一步。
有人指出,Magennis在不稳定的事情上是错误的。但是,上述说明仍然有效。
答案 2 :(得分:0)
他说,如果这样做,说orderby LastName
只有那个姓氏相同的人才会以不可预测的顺序排序。因此,如果您将其与orderby LastName, FirstName
组合使用,则可以再次预测订单(当然,第一个和姓氏相同的人除外)。
至少,这就是我的假设。