Programming

C# Dictionary: Complete Guide to Mastering Key-Value Collections

As a developer, I’ve always found dictionaries to be one of the most powerful and versatile collections in C#. They’re absolutely essential for any serious programmer working with .NET. Today, I’m going to walk you through everything you need to know about using dictionaries in C# – from basic initialization to advanced techniques like serialization.

What Exactly is a C# Dictionary?

A dictionary in C# is a collection that stores key-value pairs, where each key is unique. It’s similar to a real-world dictionary where you look up words (keys) to find their definitions (values). The C# dictionary uses a hash table data structure behind the scenes, which makes lookups incredibly fast – typically O(1) time complexity regardless of size.

Some people call dictionaries by other names:

  • Associative arrays
  • Key-value pairs
  • Hash maps
  • Lookup tables

The biggest advantage? Unlike regular arrays where you’re limited to integer indexes, dictionaries let you use practically any data type as your key – strings, custom objects, whatever makes sense for your application!

Getting Started with C# Dictionaries

Initializing a Dictionary

Before you can use a dictionary, you’ll need to include the System.Collections.Generic namespace:

using System.Collections.Generic;Code language: CSS (css)

Then, you can create a dictionary by specifying the data types for both the key and value:

// Creating a dictionary with string keys and string values
Dictionary<string, string> myDictionary = new Dictionary<string, string>();Code language: JavaScript (javascript)

You can also initialize a dictionary with values right from the start:

Dictionary<string, string> myDictionary = new Dictionary<string, string>()
{
    {"firstName", "John"},
    {"lastName", "Doe"},
    {"email", "john.doe@example.com"}
};Code language: JavaScript (javascript)

In C# 9.0 and later, you can use the new target-typed new expressions for shorter initialization:

// C# 9.0+ syntax
Dictionary<string, int> ages = new()
{
    {"John", 30},
    {"Alice", 25},
    {"Bob", 40}
};Code language: JavaScript (javascript)

Adding and Removing Items

Adding items to a dictionary is straightforward:

myDictionary.Add("country", "USA");Code language: JavaScript (javascript)

Alternatively, you can use the indexer syntax:

myDictionary["city"] = "New York"; // Adds if key doesn't exist, updates if it doesCode language: JavaScript (javascript)

Removing items is just as easy:

myDictionary.Remove("city"); // Removes the item with key "city"Code language: JavaScript (javascript)

If you need to clear the entire dictionary:

myDictionary.Clear(); // Removes all itemsCode language: JavaScript (javascript)

Accessing Dictionary Values

You can access values using the key as an index:

string name = myDictionary["firstName"]; // Returns "John"Code language: JavaScript (javascript)

But be careful! This will throw a KeyNotFoundException if the key doesn’t exist. A safer approach is to use the TryGetValue method:

if (myDictionary.TryGetValue("firstName", out string name))
{
    Console.WriteLine($"Name: {name}");
}
else
{
    Console.WriteLine("Key not found!");
}Code language: JavaScript (javascript)

Checking If a Key Exists

Before accessing or updating values, you might want to check if a key exists:

if (myDictionary.ContainsKey("firstName"))
{
    // Do something with myDictionary["firstName"]
}Code language: JavaScript (javascript)

Working with Dictionary Data

Iterating Through a C# Dictionary

Dictionaries implement IEnumerable<KeyValuePair<TKey, TValue>>, which means you can easily iterate through them:

foreach (KeyValuePair<string, string> item in myDictionary)
{
    Console.WriteLine($"Key: {item.Key}, Value: {item.Value}");
}Code language: PHP (php)

If you only need the keys or values, you can use the Keys or Values properties:

// Iterate through keys only
foreach (string key in myDictionary.Keys)
{
    Console.WriteLine($"Key: {key}");
}

// Iterate through values only
foreach (string value in myDictionary.Values)
{
    Console.WriteLine($"Value: {value}");
}Code language: PHP (php)

Merging Dictionaries

What if you need to combine two dictionaries? Let’s look at how to merge them:

Dictionary<string, string> firstDict = new Dictionary<string, string>()
{
    {"key1", "value1"},
    {"key2", "value2"}
};

Dictionary<string, string> secondDict = new Dictionary<string, string>()
{
    {"key3", "value3"},
    {"key4", "value4"}
};

// Create a new dictionary to hold the merged results
Dictionary<string, string> mergedDict = new Dictionary<string, string>();

// Add all entries from the first dictionary
foreach (var item in firstDict)
{
    mergedDict.Add(item.Key, item.Value);
}

// Add all entries from the second dictionary
foreach (var item in secondDict)
{
    mergedDict.Add(item.Key, item.Value);
}Code language: PHP (php)

With LINQ, you can make this even more elegant:

Dictionary<string, string> mergedDict = new Dictionary<string, string>();
firstDict.ToList().ForEach(x => mergedDict.Add(x.Key, x.Value));
secondDict.ToList().ForEach(x => mergedDict.Add(x.Key, x.Value));Code language: JavaScript (javascript)

Be careful with potential duplicate keys when merging! If both dictionaries have the same key, the code above will throw an exception. A safer approach might be:

Dictionary<string, string> mergedDict = new Dictionary<string, string>(firstDict);
foreach (var item in secondDict)
{
    if (!mergedDict.ContainsKey(item.Key))
    {
        mergedDict.Add(item.Key, item.Value);
    }
    // Optionally: else { mergedDict[item.Key] = item.Value; } to update existing values
}Code language: PHP (php)

In modern C# (8.0+), you can also use collection expressions:

var mergedDict = firstDict.ToDictionary(
    kvp => kvp.Key,
    kvp => kvp.Value
);

foreach (var (key, value) in secondDict)
{
    mergedDict[key] = value; // Overwrites if key exists
}Code language: PHP (php)

Advanced C# Dictionary Features

Dictionary Performance Considerations

Dictionaries in C# are optimized for fast lookups, but there are some performance considerations:

  1. Initial capacity: If you know the approximate size of your dictionary in advance, specify an initial capacity to avoid resizing operations: Dictionary<string, string> myDict = new Dictionary<string, string>(1000); // Initial capacity of 1000
  2. Custom equality comparers: For complex key types, providing a custom equality comparer can improve performance: Dictionary<string, int> caseInsensitiveDict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

Specialized Dictionary Types

The .NET Framework provides several specialized dictionary types:

  1. SortedDictionary<TKey, TValue>: Maintains keys in sorted order (useful when you need to iterate in key order).
  2. ConcurrentDictionary<TKey, TValue>: Thread-safe version for multi-threaded scenarios.
  3. ReadOnlyDictionary<TKey, TValue>: A wrapper that prevents modifications to the dictionary.

For example, to create a case-insensitive dictionary:

var caseInsensitiveDict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
caseInsensitiveDict["Hello"] = "World";
string value = caseInsensitiveDict["hello"]; // Works! Returns "World"Code language: JavaScript (javascript)

Serializing Dictionary Objects in C#

By default, .NET doesn’t support direct XML serialization of Dictionary objects. However, we can easily implement this ourselves by creating a custom class that implements the IXmlSerializable interface.

Here’s a powerful class that enables XML serialization for dictionaries:

using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Xml;

[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> :
    Dictionary<TKey, TValue>, IXmlSerializable
{
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        bool wasEmpty = reader.IsEmptyElement;
        reader.Read();

        if (wasEmpty)
        {
            return;
        }

        while (reader.NodeType != XmlNodeType.EndElement)
        {
            reader.ReadStartElement("item");
            reader.ReadStartElement("key");
            TKey key = (TKey)keySerializer.Deserialize(reader);
            reader.ReadEndElement();

            reader.ReadStartElement("value");
            TValue value = (TValue)valueSerializer.Deserialize(reader);
            reader.ReadEndElement();

            this.Add(key, value);

            reader.ReadEndElement();
            reader.MoveToContent();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        foreach (TKey key in this.Keys)
        {
            writer.WriteStartElement("item");
            
            writer.WriteStartElement("key");
            keySerializer.Serialize(writer, key);
            writer.WriteEndElement();

            writer.WriteStartElement("value");
            TValue value = this[key];
            valueSerializer.Serialize(writer, value);
            writer.WriteEndElement();
            
            writer.WriteEndElement();
        }
    }
}Code language: HTML, XML (xml)

Using the SerializableDictionary Class

Once you’ve defined this class, you can use it like any regular dictionary, but with the added benefit of serialization:

// Create a serializable dictionary
SerializableDictionary<string, int> scores = new SerializableDictionary<string, int>
{
    { "Alice", 95 },
    { "Bob", 87 },
    { "Charlie", 92 }
};

// Serialize to XML
XmlSerializer serializer = new XmlSerializer(typeof(SerializableDictionary<string, int>));
using (TextWriter writer = new StreamWriter("scores.xml"))
{
    serializer.Serialize(writer, scores);
}

// Deserialize from XML
SerializableDictionary<string, int> loadedScores;
using (FileStream fs = new FileStream("scores.xml", FileMode.Open))
{
    loadedScores = (SerializableDictionary<string, int>)serializer.Deserialize(fs);
}Code language: JavaScript (javascript)

C# Dictionary vs Other Collections

When should you use a Dictionary instead of other collections? Here’s a quick comparison:

  • Dictionary: Use when you need fast lookups by a unique key.
  • List/Array: Use when you need indexed access and don’t have a meaningful key.
  • HashSet: Use when you only care about the uniqueness of elements, not storing values.
  • SortedDictionary: Use when you need dictionary functionality with keys always sorted.

Dictionaries are often the perfect choice when you need to:

  • Map unique identifiers to objects (e.g., user IDs to user objects)
  • Count occurrences of items (e.g., word frequency counter)
  • Create lookup tables for fast access
  • Implement caching mechanisms

Real-World Examples

Example 1: Creating a Simple Cache

Dictionary<string, object> cache = new Dictionary<string, object>();

// Add to cache
cache["user:123"] = new User { Id = 123, Name = "John" };

// Check if in cache before expensive operation
if (!cache.TryGetValue("user:456", out object user))
{
    // Not in cache, fetch from database
    user = database.GetUser(456);
    cache["user:456"] = user;
}Code language: JavaScript (javascript)

Example 2: Word Frequency Counter

string text = "the quick brown fox jumps over the lazy dog";
Dictionary<string, int> wordCount = new Dictionary<string, int>();

foreach (string word in text.Split(' '))
{
    if (wordCount.ContainsKey(word))
    {
        wordCount[word]++;
    }
    else
    {
        wordCount[word] = 1;
    }
}

// Print results
foreach (var pair in wordCount)
{
    Console.WriteLine($"'{pair.Key}' appears {pair.Value} time(s)");
}Code language: PHP (php)

Example 3: Grouping Objects by Property

List<Person> people = GetPeople(); // Assume this returns a list of Person objects
Dictionary<string, List<Person>> peopleByCity = new Dictionary<string, List<Person>>();

foreach (Person person in people)
{
    if (!peopleByCity.ContainsKey(person.City))
    {
        peopleByCity[person.City] = new List<Person>();
    }
    peopleByCity[person.City].Add(person);
}

// Now you can access all people from a specific city
List<Person> newYorkers = peopleByCity["New York"];Code language: PHP (php)

Conclusion

Dictionaries are truly one of the most versatile and powerful data structures in C#. I use them constantly in my projects, from simple lookups to complex data transformations. Their lightning-fast access times and flexible key options make them perfect for countless programming scenarios.

The next time you find yourself repeatedly searching through a list or using complex conditionals to find matching items, remember—a dictionary might be the perfect solution! Start using dictionaries effectively in your C# applications, and you’ll immediately notice improvements in both code clarity and performance.

Remember that while standard dictionaries aren’t serializable out of the box, the custom SerializableDictionary class I’ve provided gives you that capability when needed.

Happy coding! 😊

Additional Resources

Rana Ahsan

Rana Ahsan is a seasoned software engineer and technology leader specialized in distributed systems and software architecture. With a Master’s in Software Engineering from Concordia University, his experience spans leading scalable architecture at Coursera and TopHat, contributing to open-source projects. This blog, CodeSamplez.com, showcases his passion for sharing practical insights on programming and distributed systems concepts and help educate others. Github | X | LinkedIn

View Comments

  • if i have transaction in D like this :
    D={a,b,c,d,e};
    1: {a,b,e}
    2: {b,c,d}
    3: {a,b,c,d}

    I wish to put into vertical format like :
    a b c d e
    1 1 2 2 1
    3 2 3 3
    3

    how would i put it into C#? FYI, my dataset I put into sql table....please very much to help!!!!

  • Dictionary mergedDictionary = new Dictionary();
    myDictionaryData1.ToList().ForEach(x => mergedDictionary.Add(x.Key, x.Value));
    myDictionaryData1.ToList().ForEach(x => mergedDictionary.Add(x.Key, x.Value));

    //above lines in your blog return error you are merging same dictionary . its will return duplicate key error

    it should be

    Dictionary mergedDictionary = new Dictionary();
    myDictionaryData1.ToList().ForEach(x => mergedDictionary.Add(x.Key, x.Value));
    myDictionaryData2.ToList().ForEach(x => mergedDictionary.Add(x.Key, x.Value));

Recent Posts

Service Worker Best Practices: Security & Debugging Guide

You've conquered the service worker lifecycle, mastered caching strategies, and explored advanced features. Now it's time to lock down your implementation with battle-tested service worker…

5 days ago

Advanced Service Worker Features: Push Beyond the Basics

Unlock the full potential of service workers with advanced features like push notifications, background sync, and performance optimization techniques that transform your web app into…

3 weeks ago

Service Workers in React: Framework Integration Guide

Learn how to integrate service workers in React, Next.js, Vue, and Angular with practical code examples and production-ready implementations for modern web applications.

1 month ago

This website uses cookies.