Dictionary<T> look-up or create made simpler

The design of a Dictionary lends itself well to a caching or identification mechanism and as a result you often see code that looks like this:

private static Dictionary<string, Employee> employees = new Dictionary<string, Employee>();

public static Employee GetByName(string name) {
  Employee employee;
  if (!employees.TryGetValue(name, out employee)) {
    employee = new Employee(whatever);
    employees.Add(name, employee);
  }
  return employee;
}

It’s not that it is particularly difficult but it can be a bit error prone and when you’re doing it over and over. What would be nicer is something that let you do:

public static Employee GetByName(string name) {
  return employees.GetOrAdd(name, () => new Employee(whatever));
}

Here’s an extension method to drop-in to a static class of your choosing that achieves just that.

public static TDictionaryValue GetOrAdd<TKey, TDictionaryValue>(
  this IDictionary<TKey, TDictionaryValue> dictionary,
  TKey key,
  Func<TDictionaryValue> newValue
) {
  TDictionaryValue value;
  if (!dictionary.TryGetValue(key, out value)) {
    value = newValue.Invoke();
    dictionary.Add(key, value);
  }
  return value;
}

[)amien

6 responses

  1. Avatar for Nick

    Heya Damien, did you mean to use the non-generic IDictionary interface in your static method signatures?

    Nick 4 August 2009
  2. Avatar for Damien Guard

    Oops, the code was right on my VS box but going from code to HTML I'd missed a couple of those pesky < bits :D

    Thanks for the heads-up.

    Damien Guard 4 August 2009
  3. Avatar for David Fowler

    Why do you call invoke on the delegate instead of using () to execute?

    Also checkout https://blogs.msdn.com/wesdyer/archive/2007/01/26/function-memoization.aspx

    Functional programming for life!

    David Fowler 5 August 2009
  4. Avatar for Will

    Nice one

    Definitely I have to get used to the use of extension methods, it seems really obvious after you've seen it, but if you haven't used extension methods it is hard for it to "pop up" :P

    Cheers!

    Will 5 August 2009
  5. Avatar for Brad Wilson

    Using double checked locking without knowing that the variable in question is marked "volatile" is a potential source of threading errors.

    Brad Wilson 7 August 2009
  6. Avatar for Mike Brown

    Interesting that this became a function on the ConcurrentDictionary class in .NET 4 ;)

    Mike Brown 27 August 2010