Two C# idioms - Dictionaries

Two C# idioms: On Dictionaries

This post is part of the series "C# idioms"

  1. Two C# idioms
  2. Another two C# idioms
  3. Two C# idioms: On Dictionaries This post
  4. Two C# idioms: On defaults and switch

This part of the C# idioms series is only about dictionaries. Let’s get rid of exceptions when working with dictionaries.

Instead of checking if a dictionary contains an item before adding it, use TryAdd

TryAdd() will return if an item was added or not to the dictionary. Unlike Add(), if the given key is already in the dictionary, TryAdd() won’t throw any exception. It will simply do nothing. The item is already there.

Before, if we added an item that already exists on the dictionary, we got an ArgumentException.

var myDictionary = new Dictionary<string, string>();
myDictionary.Add("foo", "bar");

myDictionary.Add("foo", "baz");
// ^^^
// System.ArgumentException:
//     An item with the same key has already been added. Key: foo

After, we checked first if the dictionary contains the item.

var myDictionary = new Dictionary<string, string>();

if (!myDictionary.ContainsKey("foo"))
  myDictionary.Add("foo", "bar");

Even better, let’s use TryAdd().

var myDictionary = new Dictionary<string, string>();
myDictionary.TryAdd("foo", "bar"); // true

myDictionary.Add("foo", "baz");
myDictionary.TryAdd("foo", "bar"); // false
A plain old dictionary
Do you imagine a big book when you hear 'dictionary'? Photo by Edho Pratama on Unsplash

Avoid KeyNotFoundException with TryGetValue or GetValueOrDefault

At least now, the KeyNotFoundException message contains the name of the not-found key. The old days chasing the not-found key are over.

On one hand, TryGetValue() uses an output parameter with the found value. It outputs a default value when the dictionary doesn’t contain the item. TryGetValue() dates back to the days without tuples.

On another hand, GetValueOrDefault() returns a default value or one you provide if the key wasn’t found.

Before, if we tried to retrieve a key that didn’t exist on a dictionary, we got a KeyNotFoundException.

var dict = new Dictionary<string, string>();

// ^^^
// System.Collections.Generic.KeyNotFoundException:
//     The given key 'foo' was not present in the dictionary.

After, we used TryGetValue().

var dict = new Dictionary<string, string>();

dict.TryGetValue("foo", out var foo); // false, foo -> null

dict.Add("foo", "bar");
dict.TryGetValue("foo", out foo); // true, foo -> "bar"

Even better, we use GetValueOrDefault().

var dict = new Dictionary<string, string>();

dict.GetValueOrDefault("foo"); // null
dict.GetValueOrDefault("foo", "withoutFoo"); // "withoutFoo"

dict.Add("foo", "bar");
dict.GetValueOrDefault("foo", "withoutFoo"); // "bar"

Voilà! That’s how to get rid of exception when working with dictionaries. Use TryAdd() and GetValueOrDefault(). Or, if you prefer output parameters, TryGetValue().

Don’t miss the previous C# idioms to separate view models into versions and the next two C# idioms to better work with defaults and switches.

Happy coding!