IEnumerable и порядок
У меня есть вопрос о заказе в IEnumerable
.
Насколько я знаю, перебор IEnumerable - это псевдокод, который можно записать следующим образом:
while (enumerable.HasNext())
{
object obj = enumerable.Current;
...
}
Теперь предположим, что нужно работать с отсортированной коллекцией. Можно ли в этом случае использовать IEnumerable или лучше попробовать другие средства (например, IList
) с поддержкой индексации?
Другими словами: дает ли контракт IEnumerable
какие-либо гарантии о заказе в целом?
Итак, IEnumerable
не является подходящим средством для универсального интерфейса, который гарантирует порядок. Новый вопрос: какой интерфейс или класс следует использовать для неизменяемой коллекции с порядком? ReadonlyCollection
? IList
? Оба они содержат метод Add()
(даже не реализован в предыдущем).
Мои собственные мысли: IEnumerable
не дает никаких гарантий по поводу заказа. Правильная реализация может возвращать одни и те же элементы в разном порядке в разных перечислениях (рассмотрим запрос SQL)
Я знаю о LINQ First()
, но если IEnumerable
не говорит ни слова об упорядочивании, это расширение довольно бесполезно.
Ответы
Ответ 1
IEnumerable/IEnumerable<T>
не дает никаких гарантий при заказе, но реализации, которые используют IEnumerable/IEnumerable<T>
, могут или не могут гарантировать упорядочение.
Например, если вы перечисляете List<T>
, порядок гарантирован, но если вы перечисляете HashSet<T>
, такая гарантия не предоставляется, но оба будут перечислены с использованием интерфейса IEnumerable<T>
.
Ответ 2
Детализация реализации. IEnumerable перечислит элемент - как это реализовано до реализации. Списки MOST и т.д. Работают по их естественному порядку (индекс 0 вверх и т.д.).
заключает ли договор IEnumerable какой-либо порядок в общем случае?
Нет, он гарантирует только перечисление (каждый пункт один раз и т.д.). IEnumerable не имеет гарантированного порядка, так как он также можно использовать для неупорядоченных элементов.
Я знаю о LINQ First(), но если IEnumerable не говорит ни слова об этом порядке, это расширение довольно бесполезно.
Нет, это не так, потому что у вас может быть внутренний порядок. Вы приводите SQL как пример: результат - IEnumerable, но если у меня есть принудительное упорядочение раньше (с помощью OrderBy()), то IEnumerable упорядочивается для каждого определения LINQ. AsEnumerable(). Сначала() возвращает мне первый элемент по порядку.
Ответ 3
Возможно, вы ищете интерфейс IOrderedEnumerable? Он возвращается с помощью методов расширения, таких как OrderBy()
, и допускает последующую сортировку с помощью ThenBy()
.
Ответ 4
Вы смешиваете две точки: перечисление и упорядочение.
Когда вы перечислите IEnumerable, вы не должны заботиться о порядке. Вы работаете с интерфейсом, и его реализация должна заботиться о порядке.
Например:
void Enumerate(IEnumerable sequence)
{
// loop
}
SortedList<T> sortedList = ...
Enumerate (sortedList);
Внутри метода все еще есть список с фиксированным порядком, но метод не знает об определенной реализации интерфейса и его особенности.