# Stacks

A Stack&lt;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 November 3, 2026

## After this lesson you can

- Use a Stack&lt;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](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/09/5e1688c9cfca4c92b14eead2f333fe12.png "A stack: push adds to the top, pop takes from the top")

## Push and Pop

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

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

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

while (plates.Count > 0)
{
    Console.WriteLine(plates.Pop());
}
```

```text
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:

```csharp
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;
    }
}
```

```text
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

- [Stack&lt;T>](https://www.ask-codey.com/glossary/stack-t)

## Cheat sheets

- [Stacks](https://www.ask-codey.com/cheat-sheets/advanced-collections-in-csharp-stacks-cheat-sheet)

Source: https://www.ask-codey.com/lessons/advanced-collections-in-csharp-stacks
