【问题标题】:Does LINQ to Objects keep its orderLINQ to Objects 是否保持其顺序
【发布时间】:2013-01-09 16:09:30
【问题描述】:

我有一个List<Person>,但想将它们转换为List<string>,以便进行简单处理,请执行以下操作:

List<Person> persons = GetPersonsBySeatOrder();
List<string> seatNames = persons.Select(x => x.Name).ToList();

Console.WriteLine("First in line: {0}", seatNames[0]);

LINQ to Objects 对象上的.Select() 语句是否保证不会更改列表成员的顺序?假设没有添加明确的不同/分组/排序

另外,如果先使用任意的.Where()子句,是否仍能保证保持相对顺序,还是有时会使用非迭代过滤?


正如 Fermin 上面评论的那样,这本质上是一个重复的问题。我没有选择正确的关键字来搜索 stackoverflow

Preserving order with LINQ

【问题讨论】:

标签: c# linq-to-objects


【解决方案1】:

在当前的 .Net 实现中,它使用这样的代码。但不能保证将来会实现。

private static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
  int index = -1;
  foreach (TSource source1 in source)
  {
    checked { ++index; }
    yield return selector(source1, index);
  }
}

【讨论】:

  • 我怀疑像 .Select() 这样广泛使用的方法的内部实现会被更改为以不同的顺序返回对象。
  • 数据库行没有保证顺序。列表可以。它应该绝对依赖于底层集合类型(即底层集合类型的 enumerator),并且应该保留并保证列表顺序。 Select 将使用 List 类型的枚举器,并且目前它会保留顺序,保证。
  • @Fermin 实际上在 .NET 和 .NET Core 之间的 Join 发生了变化,但一经发现就得到了纠正。
【解决方案2】:

这取决于底层的集合类型。您可能会从 HashSet 得到不一致的排序,但 List 是安全的。即使您想要的排序是隐式提供的,但如果您需要,最好定义一个显式排序。从方法名称来看,您似乎正在这样做。

【讨论】:

    【解决方案3】:

    是的,Linq Select 保证按照它传递的枚举顺序返回所有结果。像大多数 Linq 函数一样,它完全指定了它的作用。除非处理错误,这也可能是Select 的代码:

    IEnumerable<Y> Select<X, Y>(this IEnumerable<X> input, Func<X, Y> transform)
    {
        foreach (var x in input)
            yield return transform(x);
    }
    

    但正如 Samantha Branham 指出的那样,底层集合可能没有内在顺序。我见过在读取时会重新排列自己的哈希表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      • 2018-03-03
      • 1970-01-01
      • 2011-02-08
      • 2011-10-22
      • 1970-01-01
      相关资源
      最近更新 更多