Collections
Lesson 9 • Intermediate Track
Master List, Dictionary, Stack, Queue, and HashSet — the data structures that power real C# applications.
What You'll Learn
- • Create and manipulate
List<T>— the most common collection - • Store key-value pairs with
Dictionary<TKey, TValue> - • Understand Stack (LIFO) and Queue (FIFO) behaviour
- • Use
HashSet<T>for unique elements and set operations - • Choose the right collection for every situation
Real-World Analogy
Think of collections like containers in your kitchen. A List is a numbered shelf — items in order, easy to find by position. A Dictionary is a labelled spice rack — find anything instantly by name. A Stack is a pile of plates — you always take from the top. A Queue is a checkout line — first person in line gets served first.
Running C# Locally: C# requires the .NET SDK. Install it from dotnet.microsoft.com, or use online compilers like dotnetfiddle.net.
List<T> — The Go-To Collection
List<T> is a dynamically-sized array. Unlike a plain array (int[]), a List grows automatically as you add items. It's the collection you'll use most often.
List<T> — Add, Remove, Sort
Create a list of fruits, add/remove items, and sort them.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Create a List — a resizable array
List<string> fruits = new List<string>();
fruits.Add("Apple");
fruits.Add("Banana");
fruits.Add("Cherry");
fruits.Add("Date");
Console.WriteLine("All fruits:");
foreach (string fruit in fruits)
Console.WriteLine($" 🍎 {fruit}");
// Remove by value
fruits.Remove("Banana");
...Dictionary<TKey, TValue>
A Dictionary maps keys to values. Lookups by key are extremely fast (O(1) on average). Use dictionaries whenever you need to find data by a unique identifier — usernames, product IDs, configuration settings.
Dictionary — Key-Value Pairs
Store and retrieve data using string keys and integer values.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Dictionary = key-value pairs
Dictionary<string, int> ages = new Dictionary<string, int>
{
{ "Alice", 30 },
{ "Bob", 25 },
{ "Charlie", 35 }
};
// Add a new entry
ages["Diana"] = 28;
// Access by key
Console.WriteLine($"Alice is {ages["Alice"]} years old");
// Safe access with TryGetValue
...Common Mistakes
- • KeyNotFoundException: Accessing
dict["key"]when the key doesn't exist throws an exception. Always useTryGetValueorContainsKeyfirst. - • Duplicate keys: Adding a key that already exists throws an exception. Use
dict[key] = valueto overwrite, or check withContainsKey. - • Modifying during iteration: Never add or remove items while looping with
foreach— it throwsInvalidOperationException.
Stack<T> and Queue<T>
Stack follows Last-In-First-Out (LIFO) — like an undo history. Queue follows First-In-First-Out (FIFO) — like a print queue. Both are invaluable for specific patterns.
Stack & Queue — LIFO vs FIFO
Compare Stack and Queue behaviour with Push/Pop and Enqueue/Dequeue.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Stack = Last In, First Out (LIFO)
// Think of a stack of plates
Stack<string> plates = new Stack<string>();
plates.Push("Red plate");
plates.Push("Blue plate");
plates.Push("Green plate");
Console.WriteLine("=== Stack (LIFO) ===");
Console.WriteLine($"Top plate: {plates.Peek()}");
Console.WriteLine($"Remove top: {plates.Pop()}")
...HashSet<T> — Unique Elements
HashSet<T> stores only unique elements and ignores duplicates. It also supports mathematical set operations like union, intersection, and difference — perfect for tag systems, permission checks, and deduplication.
HashSet — Unique Items & Set Operations
Create a HashSet, observe duplicate rejection, and perform set operations.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// HashSet = unique elements only, no duplicates
HashSet<string> tags = new HashSet<string>();
tags.Add("csharp");
tags.Add("dotnet");
tags.Add("programming");
tags.Add("csharp"); // duplicate — ignored!
Console.WriteLine($"Tags count: {tags.Count}"); // 3, not 4
Console.WriteLine("\nAll tags:");
foreach (string tag in tags)
...Pro Tips
- 💡 Use
List<T>when order matters and you access by index. - 💡 Use
Dictionarywhen you need fast lookup by a key. - 💡 Use
Stackfor undo/redo, backtracking, and expression parsing. - 💡 Use
Queuefor task scheduling and BFS algorithms. - 💡 Use
HashSetfor fast membership tests and deduplication.
📋 Quick Reference
| Collection | Order | Duplicates | Best For |
|---|---|---|---|
| List<T> | ✅ Index | ✅ Yes | General-purpose lists |
| Dictionary | ❌ No | ❌ Keys | Key-value lookups |
| Stack<T> | LIFO | ✅ Yes | Undo, parsing |
| Queue<T> | FIFO | ✅ Yes | Task queues, BFS |
| HashSet<T> | ❌ No | ❌ No | Unique items, sets |
Lesson Complete! 🎉
You now know how to use C#'s core generic collections. Next up: handling errors gracefully with exception handling.
Sign up for free to track which lessons you've completed and get learning reminders.