Вот код:
var s = new Stack<int>();
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
var ns = new Stack<int>(s);
var nss = new Stack<int>(new Stack<int>(s));
и затем давайте посмотрим результат
tbLog.Text += "s stack:";
while(s.Count > 0)
{
tbLog.Text += s.Pop() + ",";
}
tbLog.Text += Environment.NewLine;
tbLog.Text += "ns stack:";
while (ns.Count > 0)
{
tbLog.Text += ns.Pop() + ",";
}
tbLog.Text += Environment.NewLine;
tbLog.Text += "nss stack:";
while (nss.Count > 0)
{
tbLog.Text += nss.Pop() + ",";
}
производит следующий вывод:
s stack:4,3,2,1,
ns stack:1,2,3,4,
nss stack:4,3,2,1,
Так, ns
стек вернулся s
стек и nss
стек совпадает с s
стек.
Конструктор стека, который принимает IEnumerable
, подталкивает элементы, как если бы Add
вызывали несколько раз.
Итерация по стеку повторяется в порядке «выталкивания» ... поэтому, когда вы создаете один стек из другого, он сначала добавляет верхнюю часть исходного стека, а затем помещает элемент «второй сверху» поверх этого в новом стеке и т. д. эффективно меняя его направление.
Конструктор, который вы используете для ns
an nss
, - это Stack
. Когда вы перечисляете стек, он перечисляется сверху вниз. Но при создании стека он выталкивает элементы в пронумерованном порядке. Таким образом, последний пронумерованный элемент (последний в источнике) будет наверху нового стека.
Так что да, он действительно меняет порядок элементов.
Ключ к вашему удивлению кроется в вашем вопросе:
Инвертирует ли конструктор Stack <> стек при инициализации из другого ?
ctor, о котором вы говорите, выполняет not принимает другой стек
- скорее, он принимает IEnumerable
. То есть не существует специальной обработки для создания стека
из стека
по сравнению с построением стека
из любого другого IEnumerable
.
Итак, когда вы все же пытаетесь построить стек
из стека
, исходный стек
используется в своем естественном порядке перечисления, то есть в ] заказ. А новый стек
создается путем проталкивания элементов входящего IEnumerable
. Отсюда поведение, которое вы наблюдаете.