Explore powerful built-in data structures for real-world applications
C# and .NET provide a range of generic collections that go far beyond basic arrays. If you’re building anything more than a toy app, you’ll likely use List<T>, Stack<T>, Queue<T>, or Dictionary<TKey, TValue> at some point.
This article introduces each structure, when to use it, and how to use it effectively in your projects.
πΉ List<T> β Dynamic, Ordered Collection
The List<T> is the most versatile and commonly used collection in C#. It holds items of a specific type and keeps them in the order you add them.
List<string> fruits = new List<string>();
fruits.Add("Apple");
fruits.Add("Banana");
fruits.Add("Cherry");
foreach (var fruit in fruits)
{
Console.WriteLine(fruit);
}
β Best for:
- Maintaining order
- Frequently adding/removing items
- Fast index-based access
π§ Key Methods:Add(), Remove(), Insert(), Contains(), IndexOf(), Sort()
π Stack<T> β Last In, First Out (LIFO)
A Stack<T> works just like a stack of plates: the last thing you add is the first thing to come off. Itβs perfect for undo systems, navigating history, or reversing data.
Stack<string> stack = new Stack<string>();
stack.Push("First");
stack.Push("Second");
stack.Push("Third");
Console.WriteLine(stack.Pop()); // Third
Console.WriteLine(stack.Peek()); // Second (still on top)
β Best for:
- Backtracking (undo, history)
- Temporary storage where order matters
- Reversing logic or operations
π§ Key Methods:Push(), Pop(), Peek(), Count
π¦ Queue<T> β First In, First Out (FIFO)
A Queue<T> is like a line at the bank. The first item added is the first item retrieved.
Queue<string> queue = new Queue<string>();
queue.Enqueue("Alice");
queue.Enqueue("Bob");
queue.Enqueue("Charlie");
Console.WriteLine(queue.Dequeue()); // Alice
Console.WriteLine(queue.Peek()); // Bob (next in line)
β Best for:
- Processing requests in order
- Scheduling tasks or events
- Message buffers, print queues, pipelines
π§ Key Methods:Enqueue(), Dequeue(), Peek(), Count
π Dictionary<TKey, TValue> β Fast Key Lookup
A Dictionary<TKey, TValue> stores key-value pairs. It’s like a phonebook: you look up a key (like a name) and get a value (like a phone number).
Dictionary<string, int> ages = new Dictionary<string, int>();
ages["Alice"] = 30;
ages["Bob"] = 25;
Console.WriteLine(ages["Alice"]); // 30
β Best for:
- Mapping keys to values (like IDs to objects)
- Fast lookups
- Eliminating duplicate keys
π§ Key Methods:Add(), ContainsKey(), Remove(), TryGetValue(), indexer []
π§ Which to Use and When?
| Need | Use This | Why |
|---|---|---|
| Ordered, index-based list | List<T> | Versatile, dynamic, widely supported |
| Undo or reverse logic | Stack<T> | Last-in, first-out structure |
| Process items in arrival order | Queue<T> | First-in, first-out behavior |
| Associate data by key | Dictionary<K,V> | Fast lookup using a key |
π More Examples
πΉ Stack for Undo:
Stack<string> undoHistory = new Stack<string>();
undoHistory.Push("Edit 1");
undoHistory.Push("Edit 2");
Console.WriteLine("Undo: " + undoHistory.Pop());
πΉ Queue for Tasks:
Queue<string> taskQueue = new Queue<string>();
taskQueue.Enqueue("Load Image");
taskQueue.Enqueue("Resize Image");
taskQueue.Enqueue("Save Image");
while (taskQueue.Count > 0)
{
Console.WriteLine("Processing: " + taskQueue.Dequeue());
}
πΉ Dictionary for ID Lookup:
Dictionary<int, string> products = new Dictionary<int, string>
{
{ 100, "Laptop" },
{ 200, "Tablet" },
{ 300, "Smartphone" }
};
if (products.ContainsKey(200))
Console.WriteLine(products[200]); // Tablet
π§ͺ Challenge Task
Write a simple app that:
- Stores commands in a
Stack<string>and lets the user undo them - Stores incoming usernames in a
Queue<string>and processes them in order - Uses a
Dictionary<string, int>to assign and look up user IDs
π Summary
| Type | Description | Key Feature |
|---|---|---|
List<T> | Ordered, resizable collection | Add, index, LINQ |
Stack<T> | LIFO structure | Push, Pop, Peek |
Queue<T> | FIFO structure | Enqueue, Dequeue, Peek |
Dictionary<K,V> | Key/value map | Fast key-based lookup |
β Best Practices
- Use
List<T>for most general-purpose collections - Use
Stack<T>orQueue<T>when order of access matters - Use
Dictionary<TKey, TValue>when you need fast lookups or unique keys - Always check
.ContainsKey()orTryGetValue()before accessing dictionary values - Choose the right collection based on how you need to access your data
π§βπ» Want more? Our hands-on .NET development training courses cover advanced data structures, LINQ, and custom collections β with real projects and live mentoring.