iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

List / Dictionary

C# collections: List, Dictionary, HashSet, Queue, Stack, ImmutableX, ReadOnlyX. The right structure for the operation.

C# — collections

EXAMPLE
using System.Collections.Generic;
using System.Collections.Immutable;

// ===== List<T> (most common) =====
var nums = new List<int> { 1, 2, 3, 4 };
nums.Add(5);
nums.RemoveAt(0);
nums.Contains(3);
nums.IndexOf(3);

// ===== Dictionary<K,V> =====
var ages = new Dictionary<string, int> {
    ["Alex"] = 30,
    ["Sam"] = 25,
};
ages["Alex"];           // 30
ages.TryGetValue("Lee", out var age);
ages.ContainsKey("Alex");
ages.Remove("Sam");

// ===== HashSet<T> =====
var tags = new HashSet<string> { "vip", "beta" };
tags.Add("new");
tags.Contains("vip");
tags.UnionWith(new[] { "alpha", "new" });
tags.IntersectWith(new[] { "vip", "new" });

// ===== Queue<T> and Stack<T> =====
var q = new Queue<string>();
q.Enqueue("a"); q.Enqueue("b");
q.Dequeue();              // 'a' (FIFO)

var s = new Stack<string>();
s.Push("a"); s.Push("b");
s.Pop();                  // 'b' (LIFO)

// ===== SortedDictionary<K,V> + SortedSet<T> =====
var scores = new SortedDictionary<string, int>();   // keys in sorted order
scores["alex"] = 100;
scores["bob"] = 50;
foreach (var (k, v) in scores) { /* ordered */ }

// ===== Concurrent collections =====
using System.Collections.Concurrent;
var d = new ConcurrentDictionary<string, int>();
d.TryAdd("a", 1);
d.AddOrUpdate("a", 1, (k, old) => old + 1);

var bag = new ConcurrentBag<int>();   // unordered, thread-safe
var cq = new ConcurrentQueue<int>();

// ===== Immutable collections =====
var im = ImmutableList.Create(1, 2, 3);
var im2 = im.Add(4);                   // returns new list
// im is unchanged

ImmutableArray.Create(1, 2, 3);
ImmutableDictionary<string, int>.Empty.Add("a", 1);

// ===== ReadOnly views =====
List<int> data = new() { 1, 2, 3 };
IReadOnlyList<int> view = data;       // read-only interface; data is still mutable

// ===== LINQ over collections =====
using System.Linq;
var evens = nums.Where(n => n % 2 == 0).ToList();
var sum = nums.Sum();
var byTag = users.GroupBy(u => u.Tag).ToDictionary(g => g.Key, g => g.Count());

// ===== When to use what =====
// List<T>          Default sequential collection
// Dictionary<K,V>  Key-value; O(1) average lookup
// HashSet<T>       Unique items; O(1) average lookup
// Queue / Stack    FIFO / LIFO semantics
// SortedX          When key order matters; O(log n) ops
// Concurrent       Multi-threaded access
// Immutable        Functional / persistent data structures

// ===== Patterns to internalise =====
// - Pick the structure based on the HOT operation
// - IReadOnlyList / IReadOnlyDictionary for public API surface
// - Concurrent collections instead of locking around regular ones
// - ImmutableX for snapshots / undo / sharing across threads

// ===== Pitfalls =====
// - List<T> as a hash-like API (no fast lookup; use Dictionary)
// - Modifying a collection while iterating it -> exception
// - Public List<T> property -> consumers can mutate; expose IReadOnlyList<T>
// - ConcurrentDictionary lookups in a loop without TryGetValue -> race conditions

Why it matters

C# has a rich collection toolbox. List + Dictionary + HashSet cover most needs; Queue + Stack for FIFO/LIFO; Sorted variants for ordered keys; Concurrent for threads; Immutable for snapshots. Pick by the hot operation, expose IReadOnly views to public APIs, and the code stays predictable.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
var list = new List<string> { "a", "b" };
list.Add("c");

var ages = new Dictionary<string, int>();
ages["ada"] = 36;
Try it Yourself »

Discussion

Loading…