Цикл foreach в C# гарантируют порядок оценки?

Логически, можно было бы думать, что цикл foreach в C# оценит в том же порядке как постепенное увеличение для цикла. Экспериментально, это делает. Однако на сайте MSDN, кажется, нет такого подтверждения.

Это - просто такой очевидный ответ, что они не думали для включения той информации о сайте? Или есть ли возможность, что это будет вести себя беспорядочно?

24
задан double-beep 2 February 2019 в 14:42
поделиться

4 ответа

Для массивов (обратите внимание, что System.Array реализует IEnumerable ), он будет обращаться к элементам по порядку. Для других типов ( IEnumerable или имеющих GetEnumerator ) он обращается к элементам в указанном порядке посредством чередующихся вызовов MoveNext и Current .

Стандартные состояния (ECMA-334 §13.9.5):

«Порядок, в котором проходит foreach элементы массива, как следующим образом: Для одномерных массивов элементы пересекаются при увеличении порядок индекса, начиная с индекса 0 и оканчивается индексом Длина - 1. Для многомерные массивы, элементы пройдено так, что индексы крайнее правое измерение увеличено сначала, затем следующее левое измерение, и так далее влево ».

39
ответ дан 28 November 2019 в 22:51
поделиться

Что бы это ни стоило, вы можете многое найти в Reflector . В mscorlib System.Array реализует IEnumerable (как упоминалось), а Array # GetEnumerator возвращает ArrayEnumerator . Вот тело ArrayEnumerator # MoveNext :

public bool MoveNext()
{
    if (this._complete)
    {
        this.index = this.endIndex;
        return false;
    }
    this.index++;
    this.IncArray();
    return !this._complete;
}

Это, очевидно, один пример, но ответ таков: это зависит от разработчика, и вы можете узнать большую часть того, как они работают, экспериментально или проверив исходный код. , в некоторых случаях.

5
ответ дан 28 November 2019 в 22:51
поделиться

Предостережью на каждый раз являются хэш-массивы, где порядок не гарантируется из-за ... хэш-ключи.

3
ответ дан 28 November 2019 в 22:51
поделиться

foreach построен поверх IEnumerable В контракте для счетчика на MSDN указано

Изначально перечислитель располагается перед первым элементом в Коллекция. ... Следовательно, вы должны вызвать MoveNext, чтобы переместить перечислитель к первому элементу коллекции перед чтением значения Current.

Current возвращает тот же объект, пока не будет вызван MoveNext. MoveNext устанавливает Current для следующего элемента.

Таким образом, если в базовой коллекции есть чистый «первый» элемент, и каждый элемент имеет четкий «следующий» элемент, как в случае с массивами, списками и т. Д., Тогда вы можете ожидать, что foreach вести себя логично и стабильно. Если это что-то вроде набора, у которого нет ни первой, ни следующей последовательности, тогда он может вести себя нестабильно, хотя, предположительно, без изменения состояния IEnumerable даже коллекции, которые не имеют определенного порядка, будут согласованными, поскольку их несогласованность будет более серьезной. Работа!

11
ответ дан 28 November 2019 в 22:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: