The following code defines (and tests, if you paste it into LinqPad) a class that will let you do this using +=
. However, if you are passing the dictionary around to lots of places, it won't work, because it has to hide the indexer with new
rather than overriding it (the Dictionary
's indexer isn't virtual).
One way to get around this would be by creating the DefaultingDictionary
as an implementer of IDictionary<TKey, TValue>
and within the class having a private member that's a Dictionary
, and delegating all the calls to the methods on IDictionary
through to that - except for the indexer, which you would do yourself. You still can't pass this to things expecting a Dictionary
, but you could change those things to accept an IDictionary
instead.
void Main()
{
var dict = new DefaultingDictionary<string, double>();
dict["one"] = 1;
dict["one"] += 1;
dict["two"] += 1;
Console.WriteLine(dict["one"]);
Console.WriteLine(dict["two"]);
}
class DefaultingDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public new TValue this[TKey key]
{
get
{
TValue v;
if(TryGetValue(key, out v))
{
return v;
}
return default(TValue);
}
set
{
base[key] = value;
}
}
}
Honestly, this is all a lot of work just to be able to do the +=
thing. Really you should just do the check. There's no performance benefit to this, it just makes your code more complicated. If you do the check, somebody reading it will understand exactly what's going on.