I'm tired of this dictionary idiom:
Dictionary<Guid,Contact> Contacts;
//...
if (!Contacts.ContainsKey(id))
{
contact = new Contact();
Contacts[id] = contact;
}
else
{
contact = Contacts[id];
}
It would be nice if there was a syntax that permitted the new value to be created implicitly from a default constructor if it does not exist (the dictionary knows the type of the value, after all). Anyone seen a helper (such as an extension method) that does this?
Implementation:
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary,
TKey key, Func<TValue> valueCreator)
{
TValue value;
if (!dictionary.TryGetValue(key, out value))
{
value = valueCreator();
dictionary.Add(key, value);
}
return value;
}
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary,
TKey key) where TValue : new()
{
return dictionary.GetOrAdd(key, () => new TValue());
}
Usage:
var contacts = new Dictionary<Guid, Contact>();
Guid id = ...
contacts.GetOrAdd(id).Name = "Abc"; // ok since Contact has public parameterless ctor
contacts.GetOrAdd(id, () => new Contact { Name = "John Doe" }).Age = 40;
Same as Ani's answer, but in a more unintelligible one-liner :)
/// <param name="valueCreator">The expensive value creator function.</param>
public static T GetOrAdd<S, T>(this IDictionary<S, T> dict, S key, Func<T> valueCreator)
{
return dict.TryGetValue(key, out var value) ? value : dict[key] = valueCreator();
}
Provide a delegate as value creator than value itself to prevent unnecessary object creation.
Dictionary, unfortunately, doesn't have this feature out of the box to do all this in a single lookup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With