Dictionary in C#

Dictionary in C# is a generic collection used to store data as key-value pairs. Instead of accessing values only by numeric index, you access them by a unique key. This makes dictionaries one of the most useful collections when fast lookup matters.

If you need to map a student ID to a student object, a country code to a country name, or a product code to a price, a dictionary is often a better fit than a list or an array. It expresses the relationship directly and avoids unnecessary searching through a sequence.

Because of that design, dictionaries are heavily used in caching, configuration systems, APIs, data transformation, game state management, routing tables, and business logic. They are one of the most practical collection types in everyday C# development.


What Is Dictionary in C#?

Dictionary<TKey, TValue> is a generic collection class from the System.Collections.Generic namespace. It stores pairs of keys and values, where each key must be unique within the dictionary.

using System.Collections.Generic;

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

In this example, the key type is int and the value type is string. That means each integer key is associated with one string value.

Why Use Dictionary in C#?

A dictionary is useful when you want to find a value by a meaningful key rather than by position. With a list, you may need to search one item at a time. With a dictionary, you can often access the value directly by its key.

This makes a dictionary a strong choice when identifiers, names, codes, or lookup keys are part of the problem itself. It is not just about convenience. It is about choosing a collection model that matches the shape of the data.

Syntax of Dictionary in C#

Dictionary<KeyType, ValueType> dictionaryName = new Dictionary<KeyType, ValueType>();

You can also initialize it with values during creation.

Dictionary<int, string> students = new Dictionary<int, string>
{
    { 1, "Aarav" },
    { 2, "Diya" },
    { 3, "Kabir" }
};

This syntax is common because it is concise and easy to read for small starter datasets.

Adding Items to a Dictionary

You can add key-value pairs by using the Add() method or the indexer syntax.

Dictionary<string, int> ages = new Dictionary<string, int>();
ages.Add("Aarav", 20);
ages["Diya"] = 21;

The Add() method throws an exception if the key already exists. The indexer can add a new entry or overwrite the existing value for that key.

Accessing Values by Key

The most common dictionary operation is retrieving a value by its key.

Dictionary<int, string> students = new Dictionary<int, string>
{
    { 1, "Aarav" },
    { 2, "Diya" }
};

Console.WriteLine(students[1]); // Aarav

If the key does not exist, direct index access throws an exception. That is why safe lookup methods are important in real applications.

Safe Lookup with TryGetValue

TryGetValue() is one of the most important dictionary methods because it lets you check for a key and retrieve the value safely without risking an exception for missing keys.

if (students.TryGetValue(2, out string name))
{
    Console.WriteLine(name);
}
else
{
    Console.WriteLine("Key not found");
}

This is usually better than direct index access when missing keys are a normal possible outcome.

Checking Whether a Key or Value Exists

Dictionaries provide helper methods such as ContainsKey() and ContainsValue().

bool hasKey = students.ContainsKey(1);
bool hasValue = students.ContainsValue("Diya");

ContainsKey() is especially common because dictionary logic is usually driven by keys rather than by searching through values.

Updating Values in a Dictionary

If the key already exists, you can update its value by using the indexer.

Dictionary<string, decimal> prices = new Dictionary<string, decimal>
{
    { "Keyboard", 1200m }
};

prices["Keyboard"] = 1350m;

This is useful when the key stays the same but the associated data changes over time.

Removing Items from a Dictionary

You can remove entries by key or clear the entire dictionary.

students.Remove(2);
students.Clear();

Remove() returns a boolean indicating whether the key was found and removed. This is useful when the caller needs to know whether the operation actually changed the dictionary.

Count in Dictionary

The Count property returns the total number of key-value pairs stored in the dictionary.

Console.WriteLine(students.Count);

This property is often used in diagnostics, validation, loops, and collection checks.

Iterating Through a Dictionary

You can iterate through a dictionary by reading each key-value pair. Each iteration usually returns a KeyValuePair<TKey, TValue>.

foreach (KeyValuePair<int, string> item in students)
{
    Console.WriteLine($"{item.Key} - {item.Value}");
}

You can also use deconstruction in newer syntax styles, but understanding KeyValuePair remains useful because many APIs expose it directly.

Keys and Values Collections

A dictionary exposes Keys and Values collections when you need just one side of the mapping.

foreach (int id in students.Keys)
{
    Console.WriteLine(id);
}

foreach (string studentName in students.Values)
{
    Console.WriteLine(studentName);
}

This is useful in reporting, validation, UI population, and many data transformation tasks.

Dictionary with Custom Objects

Dictionaries often store custom objects as values.

class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Dictionary<string, Product> products = new Dictionary<string, Product>
{
    { "P101", new Product { Name = "Mouse", Price = 599m } },
    { "P102", new Product { Name = "Keyboard", Price = 1299m } }
};

This pattern is common when the key is an identifier and the value is a richer business model object.

Dictionary vs List in C#

PointDictionaryList
Data modelKey-value pairsOrdered sequence
Main access styleBy keyBy index
Unique key requirementYesNo
Best use caseFast lookup by identifierOrdered collection of items
Typical exampleID to object mappingCollection of objects in display order

Choose a dictionary when lookup by key is the main operation. Choose a list when order and sequential processing are the main focus.

Dictionary vs Hashtable

Dictionary<TKey, TValue> is generic and type-safe, while older Hashtable stores objects without compile-time generic type checking. In modern C# code, dictionary is usually preferred because it is cleaner, safer, and avoids unnecessary casting.

Performance Notes for Dictionary

Dictionaries are designed for efficient key-based lookup, insertion, and update in typical cases. That is why they are commonly used for caches and lookup tables. However, they are not ideal if you need sorted data by default or if duplicate keys are part of the problem.

If duplicate keys are needed, you may need a different structure such as grouping values in a list under one key or redesigning the data model. Matching the collection to the data rules is important.

Common Mistakes with Dictionary in C#

  • Trying to add the same key twice with Add().
  • Using direct index access without checking whether the key exists.
  • Using a list for repeated key-based lookups when a dictionary fits better.
  • Assuming dictionary iteration order should be relied on for business logic.
  • Confusing key uniqueness with value uniqueness.

These mistakes usually come from misunderstanding the main purpose of the dictionary. The dictionary is about unique keys and efficient lookup, not about duplicate-key grouping or guaranteed presentation ordering.

Best Practices for Dictionary in C#

  • Use meaningful, stable keys that reflect the lookup rule clearly.
  • Use TryGetValue() when missing keys are a normal possibility.
  • Use dictionaries when lookup by identifier matters more than sequence order.
  • Store rich objects as values when one key must map to a full model.
  • Do not rely on dictionary traversal order for important application behavior unless the design specifically guarantees it.

Dictionary in Real Applications

In real systems, dictionaries are used for request headers, configuration values, translation maps, inventory keyed by SKU, object caches keyed by ID, routing data, and aggregation logic. They are practical because they make the code match the way the data is actually queried.

When the question in your code is “given this key, what value belongs to it?”, dictionary is often the right answer.

Dictionary Interview Points

For interviews, remember that dictionary is a generic key-value collection, keys must be unique, TryGetValue() is the safe lookup method, and dictionaries are commonly compared with lists, arrays, and hashtables. You should also know the difference between direct index access and key existence checks.

Another useful point is understanding that a dictionary models lookup relationships, not just storage. Choosing it is usually a design decision based on how the data is accessed.

FAQs on Dictionary in C#

What is Dictionary in C#?

Dictionary<TKey, TValue> is a generic collection that stores key-value pairs, where each key is unique and maps to one value.

Can duplicate keys be stored in a Dictionary?

No. Keys must be unique. Attempting to add the same key again with Add() causes an exception.

What is the safest way to read a value from a Dictionary?

TryGetValue() is usually the safest approach because it checks whether the key exists while returning the value if found.

When should I use Dictionary instead of List?

Use a dictionary when key-based lookup is the main operation. Use a list when order and sequential access are the main concerns.

Duplicate-Key Scenarios in Real Design

A dictionary does not support duplicate keys directly, so if one logical key can map to multiple values, you must model that explicitly. A common approach is to make the value a list or another collection, such as Dictionary<string, List<Order>>. That way, the key remains unique while the associated value can contain multiple related items.

This is a useful design point because many beginners try to force duplicate keys into a dictionary and then fight the collection instead of representing the relationship clearly.

Custom Comparers in Dictionary

Sometimes key comparison rules matter. For example, you may want string keys to be treated in a case-insensitive way. In that case, a custom comparer can be supplied when the dictionary is created.

Dictionary<string, string> headers =
    new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

This kind of configuration is common in headers, settings, and user-input mapping where case rules should not break lookup behavior.

When Dictionary Is the Right Tool

If your code keeps asking “do I have this key?” or “what value belongs to this key?”, dictionary is usually the right collection. That question pattern is often a better design signal than any raw performance discussion because it tells you how the problem is naturally shaped.