Почему расширение Linq OrderBy не влияет на список, в котором оно вызывается? - PullRequest
8 голосов
/ 08 июля 2011

Я пытаюсь написать общий метод расширения сортировки в List на основе имени столбца строки и linq.

У меня большая часть здесь, но она пока не работает. Логика взята с с этого сайта .

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 ]

11 голосов
/ 08 июля 2011

Это другой список.Вызов ToList() создает новый экземпляр List<T>, полностью отдельный от List<T>, который был передан в метод.В нем будут те же элементы, вероятно, в другом порядке, но сам список - это другой объект.

Кстати, динамический linq уже делает это, так что вы можете захотеть проверить его.Вы можете начать читать об этом здесь .

6 голосов
/ 08 июля 2011

У кого-нибудь есть какие-нибудь советы о том, как сделать эту работу соответствующим образом или, если не так, другое решение?

Если вы хотите изменить исходный список, используйте List<T>.Sort.

2 голосов
/ 08 июля 2011

Одна из основных идей LINQ заключается в том, что она не изменяет то, к чему она призвана.

OrderBy() можно вызывать на любом IEnumerable<T>, даже на тех, которые не поддерживаются чем-либо, напоминающим список (например, он создается на лету). И было бы действительно непоследовательным, если бы он делал что-то вроде: «Если источник IList<T>, сортирует его и возвращает исходную ссылку. Если этого не произойдет, создается новая отсортированная последовательность. »

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...