Dictionary<T> look-up or create made simpler
- 📅
- 📝 236 words
- 🕙 2 minutes
- 📦 .NET
- 🏷️ C#
- 💬 6 responses
The design of a Dictionary<T>
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 to Dictionary<T> look-up or create made simpler
Interesting that this became a function on the ConcurrentDictionary class in .NET 4 ;)
Using double checked locking without knowing that the variable in question is marked “volatile” is a potential source of threading errors.
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”
Cheers!
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!
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.
Heya Damien, did you mean to use the non-generic IDictionary interface in your static method signatures?