【问题标题】:Why does the Linq OrderBy extension not affect the list it is called on?为什么 Linq OrderBy 扩展不影响它被调用的列表?
【发布时间】:2011-07-08 18:59:12
【问题描述】:

我正在尝试基于字符串列名和 linq 为 List 编写通用排序扩展方法。

我这里有大部分,但现在还不行。逻辑取自this site

public static List<T> Sort<T>(this List<T> list, string sortColumn, string sortOrder) 
{
    if (string.IsNullOrWhiteSpace(sortColumn))
        return list;

    int order = sortOrder == "desc" ? -1 : 1;

    var param = Expression.Parameter(typeof(T), "x");
    var sortExpression = Expression.Lambda<Func<T, object>>(Expression.Property(param, sortColumn), param);
    list = list.AsQueryable().OrderBy(sortExpression).ToList();

    return list;
}

单步执行此代码,我看到该列表已正确排序,但是当返回时,它对我传入的列表没有影响。我猜 AsQueryable 或 OrderBy 正在内存中创建一个新对象,我不再指向相同的参考。有没有人有一些关于如何使这项工作适当地工作的提示,或者除此之外,另一种解决方案?谢谢!

【问题讨论】:

  • 你应该只是return list.AsQueryable().OrderBy(sortExpression).ToList();
  • 您意识到您的表达式不适用于内在类型? (intDateTimebool 等)

标签: c# linq generics sorting .net-4.0


【解决方案1】:

这是一个不同的列表。 ToList() 调用创建一个新的 List&lt;T&gt; 实例,与传递给该方法的 List&lt;T&gt; 完全分开。它将包含相同的项目,可能顺序不同,但列表本身是不同的对象。

顺便说一句,动态 linq 已经这样做了,所以您可能想检查一下。你可以开始阅读它here

【讨论】:

  • 没错。正如预期的那样。实际上,您可能希望传入一个 IQueryable 并返回一个 IQueryable。
  • 是的,这基本上就是我想要的。感谢您的提示!
【解决方案2】:

有没有人有一些关于如何使这项工作适当地工作的提示,或者除此之外,另一种解决方案?

如果要修改原始列表,请使用List&lt;T&gt;.Sort

【讨论】:

    【解决方案3】:

    LINQ 背后的一个基本思想是它不会修改它调用的东西。

    OrderBy() 可以在任何IEnumerable&lt;T&gt; 上调用,即使是那些没有任何类似列表的支持(例如,它是动态生成的)。如果它做了类似这样的事情,那将是非常不一致的:“如果源是IList&lt;T&gt;,则对其进行排序并返回原始引用。如果没有,则创建一个新的排序序列。”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-09
      • 2016-12-29
      • 2020-12-24
      • 2011-08-29
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      相关资源
      最近更新 更多