Stackify is now BMC. Read theBlog

C# Dictionary: How to Create One and Best Practices

By: Stackify Team
  |  February 12, 2025
C# Dictionary: How to Create One and Best Practices

The C# dictionary is one of the most important collection types/data structures you’ll use while developing your applications. You can use a dictionary to solve certain kinds of problems in a way that’s much more natural and elegant than using, say, a list. There are also significant performance gains you can obtain by using dictionaries.

That’s what this post is about: a detailed introduction to this powerful collection type. We’ll cover:

  • What’s a dictionary and basic features
  • How to create and initialize a dictionary
  • What are the main methods you must know
  • Performance considerations, common use cases, and best practices

Introduction to C# Dictionary

Let’s start by covering some C# dictionary fundamentals.

What Is a Dictionary in C#?

In C#, the dictionary class allows you to create a collection of key-value pairs. A key is a unique identifier through which you can later retrieve the value. And the value is whatever you need to store and later retrieve.

What is a dictionary good for? There are certain performance-sensitive scenarios in which dictionaries shine, and we’ll cover more of that later. But in general, dictionaries are well-suited for when you need to retrieve a unique value based on its identifier, in an efficient way.

Key Features of C# Dictionary

Using a dictionary in C# allows you to:

  • Add elements associating them with a given key
  • Retrieve an element by its key
  • Verifying whether a given key is already present in the dictionary
  • Count how many elements are in the dictionary
  • Iterate through all key-value pairs using a foreach loop
  • Obtain a list of all the keys, values, and key-value pairs

Creating a Dictionary in C#

Time to roll up your sleeves and learn how to work with a C# dictionary.

How to Declare and Initialize a Dictionary

The easiest way to declare a dictionary is using the class’s constructor to initialize an empty one:

var dic = new Dictionary<int, string>();

In the example above, we create a dictionary whose keys are of type int and values are of type string.

Adding Key-Value Pairs

Let’s say that you would like to use the dictionary from the previous example to store the names of the months, in relation to their numbers, in a one-based fashion. Use the Add method, passing first the key and then the value as arguments:

 dic.Add(1, "January");
 dic.Add(2, "February");
 dic.Add(3, "March");
 dic.Add(4, "April");
 dic.Add(5, "May");
 dic.Add(6, "June");
 dic.Add(7, "July");
 dic.Add(8, "August");
 dic.Add(9, "September");
 dic.Add(10, "October");
 dic.Add(11, "November");
 dic.Add(12, "December");

Alternatively, it is also possible to create the dictionary and add the items in one go:

var dic = new Dictionary<int, string>
{
    { 1, "January" },
    { 2, "February" },
    { 3, "March" },
    { 4, "April" },
    { 5, "May" },
    { 6, "June" },
    { 7, "July" },
    { 8, "August" },
    { 9, "September" },
    { 10, "October" },
    { 11, "November" },
    { 12, "December" }
};

The astute readers will remember that, when defining the dictionary, the key must be unique. So, what happens when you try to add an element with an already existing key? You get an exception, of course. Let’s say that after initializing the dictionary with all twelve months, you try to add another value with the key 12.

You would get a System.ArgumentException with the following message: ‘An item with the same key has already been added. Key: 12’.

These aren’t all the ways you can initialize a dictionary, but the examples are certainly the most common ones.

Working With Dictionary Methods

Let’s cover the most common methods from the Dictionary class.

Accessing Elements

You access dictionary elements using its indexer and providing a key. In the following example, we retrieve the names of all months by using numbers from 1 to 12 as the keys:

var monthNumbers = Enumerable.Range(1, 12);
foreach (int month in monthNumbers)
{
    Console.WriteLine($"The #{month} of the year is: {dic[month]}");
}

What happens if you pass the dictionary a key it doesn’t contain? You get an exception. More specifically, a System.Collections.Generic.KeyNotFoundException. And that ties nicely with the next topic.

Checking for Key or Value Existence

If, within your code, you can’t know for sure whether a key exists, then you should verify its presence before you try to access it. The same applies when adding elements: if you don’t know whether a key has already been added to the dictionary, check first. You can do that by using the ContainsKey() method:

 if (dic.ContainsKey(12))
 {
     var lastMonthName = dic[12];
 }

Unlike keys, it’s completely valid for a dictionary to have duplicated values. Duplicate values may or may not make sense for your specific use case, and that’s why you might have to use the ContainsValue() method to check for a value’s presence.

Alternatively, a more performant way to test for the existence of a value and getting it at the same time is using the TryGetValue() method.

Modifying Values

The regular Dictionary class in C# is mutable, which means you can change the values you added to it. See the following example:

 var helloWorldTranslations = new Dictionary<string, string>
 {
     { "en", "Hello, world!" },
     { "es", "Hola, mundo!" },
     { "pt", "Olá, mundo" }
 };

// oops, we forgot the upside-down exclamation mark for the Spanish one!
helloWorldTranslations["es"] = "¡Hola, mundo!";
Console.WriteLine(helloWorldTranslations["es"]); // prints '¡Hola, mundo!'

Removing Elements

Use the Remove() method to remove an element from a dictionary. This method has a few overloads, but the most well-known one receives a single argument, representing the key for the pair you wish to remove.

This method returns true if the specified key was found and the associate pair was removed, and false otherwise. That means this method, unlike others we’ve seen before, doesn’t throw an error when you provide a key that can’t be found.

if (helloWorldTranslations.Remove("es"))
{
    Console.WriteLine("Spanish translation removed");
}

What if you wanted to remove all items from the dictionary in one go? In that case, the Clear() method is what you’re looking for:

helloWorldTranslations.Clear();

Iterating Over a Dictionary

There are several ways to iterate over a dictionary using a foreach loop. For starters, here’s our sample dictionary for this example:

Dictionary<string, string> programmingAuthors = new();
programmingAuthors["Robert C. Martin"] = "Clean Code";
programmingAuthors["Donald Knuth"] = "The Art of Computer Programming";
programmingAuthors["Gang of Four"] = "Design Patterns";
programmingAuthors["Martin Fowler"] = "Refactoring";
programmingAuthors["Thomas H. Cormen"] = "Introduction to Algorithms";
programmingAuthors["Andrew S. Tanenbaum"] = "Modern Operating Systems";

Notice two things of interest here:

  • We’ve used the target type new expressions feature of C#
  • We’ve used a different, simpler syntax to add elements to our dictionary

With that in place, let’s start by first iterating through the key-value pairs (the code below uses explicit typing for the foreach variable, but of course, we can type inference as well):

foreach (KeyValuePair<string, string> author in programmingAuthors)
{
    Console.WriteLine($"Author: {author.Key}, Famous Book: {author.Value}");
}

Let’s do it again, but this time using the deconstruction syntax introduced in C# 7:

foreach (var (author, book) in programmingAuthors)
{
    Console.WriteLine($"Author: {author}, Famous Book: {book}");
}

Finally, let’s see how to iterate over only the keys and then only the values:

// If you only need the authors
foreach (string author in programmingAuthors.Keys)
{
    Console.WriteLine($"Author: {author}");
}

// If you only need the books
foreach (string book in programmingAuthors.Values)
{
    Console.WriteLine($"Book: {book}");
}

Dictionary Performance Considerations

Generally speaking, dictionaries are fast. Here’s what .NET’s documentation has to say about element retrieval:

“Retrieving a value by using its key is very fast, close to O(1), because the Dictionary<TKey,TValue> class is implemented as a hash table.”

If you don’t know what “O(1)” means, you should learn about “time complexity” and “Big-O notation.” In short, the sentence above means that retrieving a value by its key takes a fixed time, regardless of the number of elements in the dictionary.

That isn’t true 100% of the time, though:

“The speed of retrieval depends on the quality of the hashing algorithm of the type specified for TKey.”

The type used as key should have a sound algorithm for its GetHashCode() method. If different objects return the same code – in other words if there are collisions – the performance of lookups will be impacted.

Common Use Cases

Dictionaries excel in scenarios in which you need fast retrieval of an element based on its associated key. Considering this, here’s a non-exhaustive list of common use cases for dictionaries:

  • Lookup tables
  • Implementing simple caching
  • Managing object pools
  • Counting occurrences of certain pieces of data

Best Practices for Using Dictionaries

Before wrapping up, let’s cover some dictionary best practices you should be aware of:

  • Avoid exceptions when working with keys by proactively checking in scenarios in which you can’t know for sure
  • Prefer TryGetValue() when retrieving elements, because it’s faster than using Contains() then indexer, in scenarios where it’s very common for values to not be in the dictionary
  • When it comes to key types, choose immutable types that implement GetHashCode correctly
  • Consider setting an initial capacity when initializing the dictionary, if you know the maximum length the dictionary will get. This avoids internal resizes and improves performance
  • When dictionary is no longer needed, you can use Clear() to remove all key-value pairs, relieving some pressure from the garbage collector

Conclusion

In this post, you’ve learned what a dictionary is and how and when to use it. As you’ve seen, dictionaries are great when you need a fast lookup of values. That doesn’t mean, however, that dictionaries are entirely free of potential pitfalls when it comes to performance. For instance, dictionaries have a bigger memory footprint than, say, lists, because of how they’re implemented internally (dictionaries potentially need to have several arrays and linked lists).

So, this bigger overhead is something you should be aware of and, in scenarios where the fast lookup of dictionaries doesn’t make a difference, consider picking another type.

Also, regardless of whether you’re using dictionaries, it’s great to have the support of an application monitoring tool for your applications that alerts you at the first sign of potential performance problems. In that spirit, we invite you to start your free trial of Stackify today.

Improve Your Code with Retrace APM

Stackify's APM tools are used by thousands of .NET, Java, PHP, Node.js, Python, & Ruby developers all over the world.
Explore Retrace's product features to learn more.

Learn More