C# DateTime OrderBy 当列表包含一些相同的 DateTime 值时
Posted
技术标签:
【中文标题】C# DateTime OrderBy 当列表包含一些相同的 DateTime 值时【英文标题】:C# DateTime OrderBy when list contains some identical DateTime values 【发布时间】:2017-11-08 21:29:31 【问题描述】:我有一个按DateTime
属性排序的引用类型列表。其中一些具有相同的DateTime's
。例如,多个棒球比赛同时开始。
我想确认OrderBy
每次都会以相同的方式排序;也就是说因为我按照A->B->C的顺序提供了输入;输出也将是 A->B->C(所有项目都有相同的DateTime
)。
我写了一个单元测试来确认订单被保留。测试通过了。但在真正不知道发生了什么的情况下,我仍然没有信心。
有人可以帮我确认OrderBy
的行为吗?我尝试通过谷歌搜索并找不到任何确定的内容。
【问题讨论】:
您调用 OrderBy 的集合类型是什么? 你按F12了吗?根据您在 VS 中的设置,这将从 .Net Framework 加载源代码,您可以自行查找。 看看这个答案(看起来它们与列表中的 LINQ 对象相同)***.com/questions/25922348/… @d219:是的,这证实了我所害怕的。该帖子表明它不稳定。有人刚刚发布了 Orderby().Then() ,这在我的情况下似乎是一个合理的解决方案,因为我可以强制自己的排序行为而不依赖于默认(不稳定)行为。奇怪的是他删除了我即将接受它作为答案的帖子。 @sapbucket - 从那个链接然后,如果您使用的是 LINQ 对象(而不是 LINQ to SQL),我认为如果您知道这些项目总是在相同的顺序,但是如果您总是希望它们出现 A、B、C 但不知道原始顺序是否是 A、B、C,那么是的,您必须这样做。请注意,虽然我没有在实践中玩过这个! 【参考方案1】:您所询问的概念的正式名称称为Stable Sort。
知道了这一点,您可以检查documentation for Enumerable.OrderBy 并查看它确实使用了稳定的排序算法。从Remarks 部分的末尾附近:
此方法执行稳定排序;也就是说,如果两个元素的键相等,则元素的顺序保持不变。
此外,关于该问题的 cmets 中的 Linq-to-SQL 存在一些混淆。如果您的数据已经在 List<T>
对象中,那么您不再使用 Linq-to-SQL。然而,值得注意的是,Linq-to-SQL 使用IQueryable.OrderBy
而不是Enumerable.ORderBy
,而IQueryable.OrderBy
确实不保证排序稳定。您可能得到一个稳定的排序,但这取决于数据库引擎的作用。
【讨论】:
【参考方案2】:简而言之,如果 OrderBy 值相同,OrderBy 不会更改订单。因此,如果您调用它的集合已订购,那么它将保持该顺序。如果它是一个列表,那么你一切都很好,但其他集合类型不保证顺序,例如字典或哈希集,所以我想它们的顺序可能会改变,因为你不能保证它们在基础集合中的顺序。
编辑:正如有人在 cmets linq 中提到的对象 OrderBy 是一种稳定的(或确定性的排序),因此每次的顺序都是相同的,并且被认为相等的项目的顺序不会改变
【讨论】:
正是由于字典不保证顺序,我担心列表中的 OrderBy 也是如此。您是否知道我可以在哪里阅读有关此行为的官方文档? 让我到处打猎。列表保持相同的顺序,因为您可以通过索引访问它们。所以他们必须保持这个顺序,否则两次调用 myList[1] 可能会产生不同的结果,例如,情况并非如此 看这里; msdn.microsoft.com/en-us/library/bb534966.aspx 。关键段落是“此方法执行稳定排序;即,如果两个元素的键相等,则保留元素的顺序。相反,不稳定的排序不保留具有相同键的元素的顺序。 "【参考方案3】:首先确保您阅读了excelent answer of Joel。
也就是说,如果你不能依赖Linq2Object的稳定排序(例如EF),你也可以选择ThenBy
:
OrderBy(c => c.MyDate).ThenBy(n => n.MyId)
如果第一个订单有多个相同的值,您可以应用第二个订单。
【讨论】:
以上是关于C# DateTime OrderBy 当列表包含一些相同的 DateTime 值时的主要内容,如果未能解决你的问题,请参考以下文章
存储和排序同时具有 DateTime 和 Int 值的人员列表