【问题标题】:Will IOrderedEnumerable.Select() retain element order?IOrderedEnumerable.Select() 会保留元素顺序吗?
【发布时间】:2013-07-13 02:15:54
【问题描述】:

在 C# 中,是否会使用 Select() 来投影 IOrderedEnumerable 保留元素顺序的元素?

  • 如果是这样,为什么它返回一个IEnumerable,而不是一个IOrderedEnumerable
  • 如果没有,我该如何实现(除了使用foreach)?

请注意,这个问题不是 this one 的重复问题 - 我只有一个 Select() 子句,没有 Distinct()

编辑

是的,它是 LINQ to Objects。 顺便说一句,如果我实际上是在查询一些 SQL DB,答案会有什么不同吗?

【问题讨论】:

  • 可能。虽然我不使用select,但我经常通过首先对结果进行排序然后调用SkipTake 来获取与当前页面相关的这些结果的子集来进行结果分页。订单始终得到可靠维护,因此我希望它在Select 期间也能正常工作...只需测试一下即可
  • 是LINQ to Objects吗?
  • 在这篇文章stackoverflow.com/questions/8518557/…中有更多关于何时使用IOrderedEnumerable(以及它的用途,主要是应用二级排序标准)的详细信息
  • stackoverflow.com/a/204777/477878 可能会有所帮助
  • Select() 不会更改项目的顺序,但编译器无法知道序列是否仍然是有序的。例如:new int[]{1,3,2}.Select(x => randomInstance.Next())

标签: c# ienumerable iorderedenumerable


【解决方案1】:

Select 不会更改元素顺序。它是streaming operator (MSDN),表示它按照源的顺序处理源元素,并一个一个地产生投影元素。

因此,如果您正在对有序源进行投影,则投影结果将保留源元素的顺序。


还有一件事——你可能想知道为什么结果没有实现IOrderedEnumerable<T>

int[] items = { 2, 3, 1, 8, 5 };
IEnumerable<int> query = items.OrderBy(i => i).Select(i => i);
bool isOrdered = query is IOrderedEnumerable<int>; // false

这是因为Select 运算符返回新的迭代器对象(在本例中为WhereSelectArrayIterator),它从源集合(在本例中为OrderedEnumerable)中一一读取项目,投影项目,并返回投影。这个新的迭代器对象没有实现IOrderedEnumerable&lt;T&gt;接口,它只是简单的IEnumerable&lt;T&gt;。有序集合现在是迭代器的来源,而不是迭代器本身。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    相关资源
    最近更新 更多