为什么Linq OrderBy扩展名不会影响它被调用的列表?

时间:2011-07-08 18:59:13

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

我正在尝试根据字符串列名和linq编写一个通用的排序扩展方法。

我在这里有大部分内容,但它还没有奏效。逻辑来自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正在内存中创建一个新对象,我不再指向相同的参考。有没有人有一些关于如何使这项工作适当的提示,或者除此之外,另一种解决方案?谢谢!

3 个答案:

答案 0 :(得分:11)

这是一个不同的列表。 ToList()调用会创建一个新的List<T>实例,与传递给方法的List<T>完全分开。它将具有相同的项目,可能以不同的顺序,但列表本身是一个不同的对象。

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

答案 1 :(得分:6)

  

有没有人有关于如何正确地开展这项工作的一些提示,或者除此之外,还有其他解决方案?

如果要修改原始列表,请使用List<T>.Sort

答案 2 :(得分:2)

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

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