This came up a little while in a newsgroup question, and Marc Gravell and I worked out a solution between us. I’ve finally included it in MiscUtil (although not released it yet – there’s a lot of stuff ready to go when we’ve finalised namespaces and updated the website etc) but I thought I’d share it here.
How often have you written code to do something like counting word frequencies, or grouping items into lists? I know a lot of this can be solved with LINQ if you’re using .NET 3.5, but in .NET 2.0 we’ve always been nearly there. Dictionaries have provided a lot of the necessary facilities, but there’s always the bit of code which needs to check whether or not we’ve already seen the key, and populate the dictionary with a suitable initial value if not – a count of 0, or an empty list for example.
There’s something that 0 and “empty list” have in common. They’re both the results of calling new
TValue() for their respect
TValue types of
List<Whatever>. Can you see what’s coming? A generic extension method for dictionaries whose values are of a type which can use a parameterless constructor, which returns the value associated with a key if there is one, or a new value (which is also inserted into the dictionary) otherwise. It’s really simple, but it’ll avoid duplication all over the place:
Note: This code has been updated due to comments below. Comments saying “Use TryGetValue” referred to the old version!
where TValue : new()
if (!dictionary.TryGetValue(key, out ret))
ret = new TValue();
dictionary[key] = ret;
The usage of it might look something like this:
foreach (string word in someText)
dict[word] = dict.GetOrCreate(word)+1;
I’m not going to claim this will set the world on fire, but I know I’m fed up with writing the kind of code which is in
GetOrCreate, and maybe you are too.
Additional overloads are available to specify either a value to use when the key is missing, or a delegate to invoke to create a value.