Stacks

A Stack<T> hands values back newest first, last in, first out. Push adds to the top, Pop takes from the top, and Peek looks without taking. Undo is the classic use.

Journeyman · C# · Updated

After this lesson you can

  • Use a Stack<T> for last-in, first-out work, with Push, Pop and Peek
  • Choose between a queue and a stack for a job

Key takeaways

  • A Stack<T> is last in, first out (LIFO): values come back newest first, the reverse of the order they went in.
  • Push adds to the top, Pop removes and returns the top, and Peek returns the top without removing it.
  • Pop and Peek on an empty stack throw an InvalidOperationException, so check Count first or use TryPop.
  • Undo is the classic stack. Push the state before each change, and pop the most recent one to go back a step.
  • Use a queue when the oldest should be handled first, and a stack when the newest should.

A Stack<T> works like a stack of plates: you put a plate on the top, and you take a plate from the top. The last plate added is the first one taken: last in, first out, or LIFO.

A stack: push adds to the top, pop takes from the top

Push and Pop

Stack<string> plates = new Stack<string>();

plates.Push("Emily");
plates.Push("Lucas");
plates.Push("Sophia");
plates.Push("Mason");

Console.WriteLine(quot;On top: {plates.Peek()}");

while (plates.Count > 0)
{
    Console.WriteLine(plates.Pop());
}
On top: Mason
Mason
Sophia
Lucas
Emily

The values came out in the reverse of the order they went in.

Member Does
Push(value) Puts the value on top
Pop() Removes the value on top, and returns it
Peek() Returns the value on top, without removing it
Count How many values are on the stack
TryPop(out value) Like Pop, but returns false instead of failing when the stack is empty

Like a queue, Pop() and Peek() on an empty stack throw an InvalidOperationException, so check Count or use TryPop.

Undo

The classic use of a stack is undo. Every change is pushed; undo pops the most recent one:

Stack<string> history = new Stack<string>();
string text = "";

Type("Hello");
Type(", world");
Type("!!!");
Console.WriteLine(text);

Undo();
Console.WriteLine(text);
Undo();
Console.WriteLine(text);

void Type(string words)
{
    history.Push(text);
    text += words;
}

void Undo()
{
    if (history.TryPop(out string? previous))
    {
        text = previous;
    }
}
Hello, world!!!
Hello, world
Hello

Each Type pushes the text as it was before the change. Undo pops the most recent one and puts it back, so changes come off in the reverse of the order they were made. The Back button in a browser works the same way.

Queue or stack?

Question Use
Should the oldest be handled first? A queue (FIFO): a line, a waiting list, orders to make
Should the newest be handled first? A stack (LIFO): undo, the browser's Back button, a pile of plates

Check yourself

2 questions to try on the lesson page.

So what

A stack remembers in reverse: whatever happened last comes back first. Whenever you need to go back step by step, through edits, pages or moves in a game, a stack does the remembering.

Key terms

Cheat sheets