Почему расширение Linq OrderBy не влияет на список, в котором оно вызывается?
Я пытаюсь написать общий метод расширения сортировки для списка на основе имени столбца строки и 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 ответов
Это другой список. The ToList()
вызов создает новый List<T>
экземпляр, полностью отдельный от List<T>
Это было передано в метод. В нем будут те же элементы, возможно, в другом порядке, но сам список-это другой объект.
кстати, dynamic linq уже делает это, поэтому вы можете проверить это. Вы можете начать читать об этом здесь.
есть ли у кого-нибудь советы о том, как сделать эту работу подходящей или запретить это, другое решение?
Если вы хотите изменить исходный список, используйте List<T>.Sort
.
одна из основных идей LINQ заключается в том, что он не изменяет вещи, которые он призвал.
OrderBy()
можно вызвать на любой IEnumerable<T>
, даже те, которые не подкреплены ничем, напоминающим список (например, он генерируется на лету). И было бы действительно непоследовательно, если бы он сделал что-то вроде: "Если источник IList<T>
, сортирует его и возвращает исходную ссылку. Если это не так, создает новую отсортированную последовательность."