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().