When working with collections in C#, it’s tempting to use a List for everything. After all, it’s flexible, efficient, and familiar.
But when your use case revolves around pushing and popping elements (Last-In, First-Out behavior), Stack is the better choice.
The Common Misuse of List
Many developers implement stack-like behavior with a List :
var list = new List<int>();
// Push
list.Add(10);
list.Add(20);
// Peek
int value = list[^1];
// Pop
list.RemoveAt(list.Count - 1);
It works, but it’s not optimal:
- You’re relying on RemoveAt, which isn’t semantically clear.
- There’s more room for mistakes (like forgetting to use the last index).
- List is optimized for random access, not stack-like behavior.
A better example if we have the following code
var value = list[^1];
list.RemoveAt(list.Count - 1);
If you accidentally do list.RemoveAt(0) , you just killed the wrong element (and it’s O(n) because it shifts the entire array).
The element at List[0] is discarded. But now, everything after it must shift left by one to fill the gap
Before: [ A, B, C, D ]
RemoveAt(0)
After: [ B, C, D, _ ]
The Right Tool Stack
What is a stack ?
A Stack in C# is a Last-In, First-Out (LIFO) collection.
Think of it like a stack of plates:
- You add a plate on top (push)
- You look at the top plate (Peek)
- You remove the top plate (Pop)
The last item you put in is the first one that comes out.
var stack = new Stack<int>();
// Push
tack.Push(10);
stack.Push(20);
// Peek
int value = stack.Peek();
// Pop
stack.Pop();
Time Complexity of Operations
Push → O(1)
Adds an item on top of the stack.
Peek → O(1)
Reads the top item without removing it.
Pop → O(1)
Removes the top item.
All these are O(1) operations, unlike List where removing at the wrong index can be O(n) because of shifting.
Top comments (0)