OrderBy и List vs. IOrderedEnumerable
Я столкнулся с неожиданной проблемой со следующим кодом.
List<string> items = new List<string>();
items = items.OrderBy(item => item);
Этот код генерирует ошибку:
Невозможно неявно преобразовать тип 'System.Linq.IOrderedEnumerable' в 'System.Collections.Generic.List'. Явное преобразование существует (вы пропускаете листинг?)
Кажется, я могу изменить items
на тип IEnumerable<string>
, и ошибка исчезнет. Но мне нужно добавить элементы в список, который IEnumerable
не поддерживает.
Может кто-нибудь помочь мне понять эту ошибку и какое самое простое решение? Можно ли просто привести результат?
Ответы
Ответ 1
Почему бы просто не отсортировать список на месте с помощью метода экземпляра Sort()
; то вы можете добавить элементы к нему позже, если хотите:
List<string> items = GetSomeItems();
items.Sort();
Или используйте упорядоченную коллекцию, как двоичное дерево поиска. SortedSet<T>
может соответствовать счету, в зависимости от ваших потребностей.
Решение, предложенное другими:
items = items.OrderBy(item => item).ToList();
... создает новый список с оригинальными элементами в новом порядке. Это полезно только в том случае, если вам необходимо сохранить первоначальный заказ для какой-либо другой цели; это скорее более бесполезно для памяти, чем сортировка списка на месте.
Что касается понимания ошибки, это просто: List<T>
не является подтипом IOrderedEnumerable<T>
, поэтому нет никакого неявного преобразования ссылок между ними. Явное предложение, которое предлагает компилятор, удовлетворит компилятор, но он не будет работать во время выполнения, потому что объект, возвращаемый OrderBy<T>
, не наследует от List<T>
.
ИЗМЕНИТЬ
Пример List<T>.Sort(Comparison<T>)
, предполагая, что тип MyType
имеет свойство Key
некоторого типа типа T, где T : IComparable<T>
:
List<MyType> items = GetSomeItems();
items.Sort((a, b) => a.Key.CompareTo(b.Key));
Ответ 2
Вам нужно преобразовать IEnumerable
в List
. Попробуйте следующее:
items = items.OrderBy(item => item).ToList();
Ответ 3
Попробуйте это
items = items.OrderBy(item => item).ToList();
Ответ 4
Вам нужно использовать метод LINQ ToList()
items = items.OrderBy(item => item).ToList();
Вы не можете напрямую с помощью IEnumerable < > to List < >
Ответ 5
Для сортировки списка строк вам не нужен Linq в первую очередь - просто используйте Sort()
:
List<string> items = new List<string>();
//add items here
items.Sort();
Ответ 6
OrderBy() - это метод расширения IEnumerable, а не List.
Когда компилятор встречает метод расширения OrderBy(), он переводит переменную диапазона в IOrderedEnumerable, где он может выполнять требуемую сортировку с помощью метода CreateOrderedEnumerable, используя IComparer et al. После сортировки компилятор выплескивает переменную как IEnumerable - обычно.
Предложение: используйте ключевое слово var, чтобы ввести "элементы" в предложение LinQ.
Конечно, варианты, предложенные выше, используя методы Sort() и ToList(), будут работать, однако использование их связано с жадными операторами, и вы теряете преимущество ленивой загрузки.
Здесь хорошая разбивка:
С# Сортировка и сравнение OrderBy между запуском Sort() и OrderBy().