In this short blog post, I want to showcase three nice tricks you can do with everybody's favorite data type: the dictionary.
It is a versatile data structure, and we can make it even more versatile!
Trick 1: Pass a StringComparer to the constructor
When you're handling strings as keys, it can happen that you don't really care if they are uppercase or lowercase - so you want to have a case-insensitive key collection.
Sure, you could do ToLower or ToUpper everywhere you ask for a key, but there are multiple problems:
- You can forget to do that in new places or if you refactor
- You have this knowledge spread all over the place.
- Useless allocations you wouldn't need
So a better choice is to pass in a StringComparer as a constructor argument to the Dictionary itself. Showing clearly the intent in a single point:
var dictionary = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase)
{
    { "foo", 1 },
    { "bar", 2 }
};
_ = dictionary.ContainsKey("FOO"); // true
_ = dictionary.ContainsKey("Foo"); // true
_ = dictionary.ContainsKey("foo"); // true
_ = dictionary["FOO"]; // 1
_ = dictionary["Foo"]; // 1
Trick 2: TryGetValue
TryGetValue is a nice method to get a value from a dictionary without having to check if the key exists first. It returns a bool indicating if the key was found and the value is written to an out parameter. So instead of writing the following:
Dictionary<string, int> dictionary = GetDictionary();
if (dictionary.ContainsKey("foo"))
{
    var value = dictionary["foo"];
    // do something with value
}
You can write the following:
Dictionary<string, int> dictionary = GetDictionary();
if (dictionary.TryGetValue("foo", out var value))
{
    // do something with value
}
Trick 3: Using GetValueOrDefault When Key Does Not Exist
If you attempt to get a value from a dictionary using a key that doesn't exist, it throws a KeyNotFoundException. But there is an extension, called GetValueOrDefault method to return a default value when the key doesn't exist:
Dictionary<int, string> dictionary = new()
{
    { 1, "foo" }
};
_ = dictionary.GetValueOrDefault(1, "not found"); // foo
_ = dictionary.GetValueOrDefault(2, "not found"); // not found
You could build this function on your own like this:
public static TValue GetValueOrDefault<TKey, TValue>(
  this Dictionary<TKey, TValue> dictionary,
  TKey key,
  TValue fallback)
{
  if (dictionary.TryGetValue(key, out TValue value))
  {
    return value;
  }
  return fallback;
}



