Generic Collections (List, Dictionary, HashSet, Stack/Queue) Masterclass
Welcome to Phase 5 (Chapter 13): C# Generic Collections (List, Dictionary, HashSet, Stack & Queue) Masterclass! Unlike fixed-size arrays, collections dynamically grow and shrink as data is added or removed. According to official Microsoft documentation, generic collections in System.Collections.Generic improve type safety and performance by eliminating boxing/unboxing overhead.
List<T> is a dynamic array that grows automatically when capacity is reached. Dictionary<TKey, TValue> is a high-speed Hash Table that provides O(1) key lookups.
using System.Collections.Generic;
// 1. List โ Dynamic Resizable Array
List<string> courses = new() { "C#", "ASP.NET Core", "SQL" };
courses.Add("Azure Cloud");
courses.Remove("SQL");
Console.WriteLine($"Course count: {courses.Count}");
foreach (string c in courses) Console.WriteLine($"Course: {c}");
// 2. Dictionary โ Fast O(1) Key-Value Lookup
Dictionary<int, string> employees = new()
{
{ 101, "Alice" },
{ 102, "Bob" },
{ 103, "Charlie" }
};
if (employees.TryGetValue(102, out string? empName))
{
Console.WriteLine($"ID 102 Name: {empName}");
}
Other generic collections suit specific algorithm patterns:
// 1. HashSet โ Unordered Collection of Unique Elements
HashSet<int> uniqueIds = new() { 1, 2, 2, 3, 3, 3 };
Console.WriteLine($"Unique ID count: {uniqueIds.Count}"); // 3
// 2. Queue โ FIFO (First-In, First-Out)
Queue<string> ticketQueue = new();
ticketQueue.Enqueue("User 1");
ticketQueue.Enqueue("User 2");
Console.WriteLine($"Processing: {ticketQueue.Dequeue()}"); // User 1
// 3. Stack โ LIFO (Last-In, First-Out)
Stack<string> undoStack = new();
undoStack.Push("Action 1");
undoStack.Push("Action 2");
Console.WriteLine($"Undo Action: {undoStack.Pop()}"); // Action 2
Q1: Why are Generic Collections preferred over ArrayList?
Generic collections like List<int> store items without casting them to object, eliminating Boxing/Unboxing and enforcing compile-time type safety.
Q2: How do I choose the right collection?
Use List<T> for ordered sequential access; Dictionary<K,V> for fast key lookup; HashSet<T> for uniqueness; Queue<T> for FIFO processing; and Stack<T> for LIFO undo/redo operations.