Skip to main content
๐Ÿ“œ WAYPOINT LESSON

Dictionary<TKey, TValue> โ€” lookup by key

โญ beginnerโณ 13 min read๐Ÿ“ Lesson 31 of 85

Add, indexing, TryGetValue, ContainsKey โ€” and why the indexer throws on a missing key.

Keys map to values

var ages = new Dictionary<string, int>();
ages["an"] = 30;               // insert or overwrite
ages.Add("binh", 25);          // THROWS if "binh" already exists
Console.WriteLine(ages["an"]); // 30 โ€” THROWS if "an" is absent

The indexer creates or overwrites; Add refuses duplicates. Reading ages["missing"] throws KeyNotFoundException โ€” the single most common dictionary crash. Two safe reads:

if (ages.TryGetValue("missing", out int age))
    Console.WriteLine(age);    // out param set only when found

if (ages.ContainsKey("missing")) { ... }   // check without reading

TryGetValue is preferred: one lookup instead of two (ContainsKey then indexer), and it gives you the value.

Counting things โ€” the classic pattern

var votes = new Dictionary<string, int>();
foreach (string ballot in ballots)
{
    votes.TryGetValue(ballot, out int n);
    votes[ballot] = n + 1;      // read-modify-write
}

TryGetValue with out conveniently yields 0 when the key is absent, so the pattern handles first-votes without a branch. Counting, grouping, and deduplicating (next lesson) are the three dictionary superpowers โ€” every practice challenge here is one of them.

Iteration

foreach (var kv in ages) yields KeyValuePair<string,int> โ€” read kv.Key/kv.Value. Dictionaries have no defined order; never write logic that depends on enumeration order.