In Wintellect's PowerCollections, there's a GetValueElseAdd
which works like this:
if ( collection.GetValueElseAdd( key, ref value))
{
// just added, value unmodified
}
Or
// factory method only gets called if the key is not present.
if ( collection.GetValueElseAdd( key, out value, () => thingFactory.CreateNew()))
{
// just added; value contains factory result
}
In both cases, there's only one walk through the hashes to isolate where the value is going to sit. (See http://stackoverflow.com/questions/2138982/what-happens-to-c-dictionaryint-int-lookup-if-the-key-does-not-exist/2138988#2138988 for more discussion of the tradeoffs)
The question is, why has functionality like this not made it into the BCL, especially given that pretty much all of the rest of PowerCollections got sucked in via 3.5/LINQ and the new collections added in 4.0?
Is it because the general usage pattern is that one only does an Add
once whereas you're generally only hitting the equivalent of the TryGetValue
path with a single hashtable lookup the bulk of the time?
Is it because this is much more valuable in a tree than in a hashtable (could only find this implementation on the net but I think it was on more than just an OrderedList collection)
EDIT: See also the post linked in the comment's on Fredrik's response which discusses multithreading considerations for Sychronized variants of a collection.
Or is there another idiom I'm missing? If only Peter Golde was here!