In C#, raw arrays (string[]) are fixed in size and difficult to manage. Modern applications rely on the Generic Collections found in System.Collections.Generic. Choosing the right collection can mean the difference between an app that is "O(1) Instant" and an app that is "O(n) Sluggish."
The List is the go-to collection. It is essentially a dynamic array that automatically resizes itself. However, searching for an item in a list requires scanning every single element one by one (O(n)).
var names = new List<string> { "Sandeep", "Ankit" };
names.Add("John"); // O(1) mostly
bool exists = names.Contains("Sandeep"); // O(n) - Slow for 1 Million items!
A Dictionary uses a Hash Table. It allows you to look up any value using a key almost instantly (O(1)), regardless of whether you have 10 items or 10 Million items.
var userCache = new Dictionary<int, User>();
userCache.Add(1, new User { Name = "Sandeep" });
// Instant lookup! No scanning required.
var user = userCache[1];
A HashSet is like a Dictionary but only stores unique keys. It is the best way to handle "Distinct" lists or perform high-speed existence checks without the overhead of key/value pairs.
Q: "Why should we specify a 'Capacity' when initializing a new List or Dictionary if we already know the expected size?"
Architect Answer: "Memory Fragmentation and CPU cycles. When a `List` fills up, the CLR has to allocate a brand-new, larger array on the heap, copy all existing items to the new array, and mark the old array for Garbage Collection. This causes 'GC Pressure' and pauses your application. By passing a capacity—`new List