Stack.ToList() - порядок элементов?

При использовании метода расширения .ToList() в Stack<T>, является ли результат таким же, как popping каждого элемента и добавление в новый список (назад от того, что было нажато)?

Если это так, это потому, что он действительно выполняет итерацию по каждому элементу, или он сохраняет внутренние элементы в обратном направлении и сбрасывает массив в новый List<T>?

Ответ 1

Сам по себе Stack не имеет метода ToList, это метод расширения из класса Enumerable. Поскольку эти методы расширения имеют дело только с IEnumerable<T>, можно предположить, что ToList выполняет итерации по элементам стека для создания нового списка (или, по крайней мере, действует точно так же, как если бы - методы Enumerable иногда проверяют введите аргумент и используйте оптимизированную реализацию).

Интересно, что в документации не указано, в каком порядке перечислен стек, но пример кода показывает порядок, а примеры являются частью документации. Кроме того, на практике изменение порядка итераций нарушило бы настолько много кода, что его было бы слишком рискованно менять сейчас.

Я также проверил с отражателем; Stack<T> хранит свои элементы в массиве с самым нижним элементом с индексом 0, но его Enumerator выполняет итерацию массива в обратном порядке. Поэтому первым элементом, который выходит из итератора, является верхняя часть стека.

Ответ 2

ToList будет повторяться в том же порядке, как если бы вы сделали это:

foreach (T item in stack)

docs для GetEnumerator() явно не указывать порядок, насколько я могу судить, но пример показывает, что он будет итерации как если бы он появлялся. Поэтому, если вы нажмете 1, 2, 3, 4, 5, то ToList даст вам 5, 4, 3, 2, 1.