Dictionary Collections

Vaibhav • September 10, 2025

In the previous article, we explored List<T>, which is excellent when we need to store items sequentially and access them by index. But what if we want to look up values by a meaningful key rather than a number? That’s where Dictionary<TKey, TValue> comes in.

What is a Dictionary?

A dictionary is a collection that stores data in key–value pairs. Each key must be unique, and each key maps to exactly one value. Keys act like labels that allow us to retrieve values quickly without needing to search through the whole collection.

Dictionary<TKey, TValue> is part of the System.Collections.Generic namespace. You must specify two types - one for the key and one for the value (e.g., Dictionary<string, int>).

Declaring and Initializing a Dictionary

Let’s start with a simple example - mapping country names to their capitals:

// Declaring and initializing a dictionary
Dictionary<string, string> capitals = new Dictionary<string, string>();

// Adding key–value pairs
capitals.Add("India", "New Delhi");
capitals.Add("USA", "Washington D.C.");
capitals.Add("Japan", "Tokyo");

// Using collection initializer
Dictionary<string, int> ages = new Dictionary<string, int>
{
    { "Alice", 30 },
    { "Bob", 25 },
    { "Charlie", 35 }
};

With a dictionary, we don’t need to remember array indexes - instead, we can retrieve values directly using meaningful keys.

Accessing Values

We use the [] indexer to access values by key:

Console.WriteLine(capitals["India"]); // Output: New Delhi

Accessing a non-existent key with [] throws a KeyNotFoundException. Use TryGetValue() if you’re unsure whether a key exists.

if (capitals.TryGetValue("France", out string capital))
{
    Console.WriteLine(capital);
}
else
{
    Console.WriteLine("Key not found!");
}

Adding and Updating Values

There are two common ways to add or update values in a dictionary:

  • Add(key, value) - inserts a new pair (throws an exception if key exists).
  • dict[key] = value - inserts if the key doesn’t exist, updates otherwise.
// Using Add()
capitals.Add("Germany", "Berlin");

// Using indexer to update
capitals["Japan"] = "Kyoto"; // updates the value

Removing Elements

Dictionaries provide a simple Remove() method:

capitals.Remove("USA");

After removal, the key–value pair is gone and cannot be accessed.

Iterating Over a Dictionary

Since dictionaries don’t use numeric indexes, we iterate over them with foreach:

foreach (var kvp in capitals)
{
    Console.WriteLine($"{kvp.Key} - {kvp.Value}");
}

Here kvp (KeyValuePair) exposes both the key and value.

Checking for Keys and Values

Dictionaries offer two helpful methods:

  • ContainsKey(key)
  • ContainsValue(value)
if (capitals.ContainsKey("India"))
    Console.WriteLine("India is in the dictionary!");

How Dictionaries Work Internally

Dictionaries use a hash table under the hood:

  • Each key is passed through a hashing function to compute an index (called a bucket).
  • The key–value pair is stored in that bucket.
  • If multiple keys hash to the same bucket, the dictionary uses collision resolution (usually chaining).

Lookup, insert, and remove operations in a dictionary are usually O(1) - constant time - but in the worst case (many collisions), they can degrade to O(n). However, with a good hashing strategy, this is rare.

Performance Considerations

Dictionaries are optimized for fast lookups, but there are things to keep in mind:

  • Keys must be unique - attempting to insert duplicates will throw an exception.
  • Keys must be immutable (e.g., strings, integers). Using mutable objects as keys can cause bugs.
  • Memory usage is higher than arrays or lists due to hashing overhead.

Use TryGetValue() or ContainsKey() before accessing a key to avoid runtime exceptions.

Real-World Example

Suppose we’re building a student gradebook system. A dictionary is perfect because each student has a unique ID, and we want to quickly retrieve their grade:

Dictionary<int, string> gradeBook = new Dictionary<int, string>();

// Adding students
gradeBook.Add(101, "A");
gradeBook.Add(102, "B");
gradeBook.Add(103, "C");

// Retrieving
Console.WriteLine(gradeBook[101]); // Output: A

// Updating
gradeBook[103] = "B+";

// Iterating
foreach (var entry in gradeBook)
{
    Console.WriteLine($"ID: {entry.Key}, Grade: {entry.Value}");
}

Dictionaries vs Lists

When should you use a dictionary instead of a list?

  • Use a List: When order matters, and you access items primarily by position.
  • Use a Dictionary: When quick lookups by key are important, and order is less important.

Summary

Dictionary<TKey, TValue> is one of the most powerful and commonly used collections in C#. By mapping unique keys to values, it allows lightning-fast lookups, updates, and removals. Understanding how dictionaries use hashing internally will help you design more efficient programs. In the next section, we’ll explore another specialized collection - HashSet<T>, which focuses on uniqueness of values.