-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Proposal: Dictionary<K,V>.Update to replace a value without double-lookup #36942
Comments
Tagging subscribers to this area: @eiriktsarpalis |
Personally, I would appreciate all the ConcurrentDictionary methods on Dictionary: AddOrUpdate However, I think it might make more sense to add them as extension methods/DIMs on IDictionary. |
@YairHalberstadt If they were added as extension methods, I don't think they'd be able to avoid the double lookup. |
@jnm2 I care less about the double lookup and more about convenience |
Why do you think it is excessive? The |
@eiriktsarpalis The Update method would first look up the internal slot and throw KeyNotFoundException if none exists, then it would invoke the callback to obtain a value and assign it to the slot without a second lookup. |
Duplicate of #15059 |
@eiriktsarpalis I disagree. None of what's proposed in #15059 would allow writing a new value based on an existing value without the double-lookup problem. An update in my scenario requires an existing value (and bubble up the |
Fair point, however there is significant overlap between the two requests and as such it's best that we consolidate into one conversation. @layomia is already working on prototyping an implementation of #15059 so it might make sense to evaluate an update variant at the same time. FWIW my opinion is we should be considering an |
Background and Motivation
I have a class that implements copy-on-write semantics:
This class is used as a Dictionary value, but currently it requires a double lookup in order perform an update operation:
It certainly feels like something could be done to avoid the second indexing operation there.
Proposed API
#26848, who had pretty much the same problem, suggested copying the signature of
ConcurrentDictionary<K,V>.AddOrUpdate
. This seems a bit excessive, so I propose a simpler version:public partial class Dictionary<TKey, TValue> { + public void Update(TKey key, Func<TKey, TValue, TValue> updateValueFactory); }
This would throw
KeyNotFoundException
if the providedkey
doesn't exist.Usage Examples
Alternative Designs
I have tried
DictionarySlim
fromMicrosoft.Experimental.Collections
, and while itsGetOrAddValueRef(TKey)
method would work for me for the updating scenario, that type lacks some other things that I'm depending on from the normalDictionary
, namely:Keys
which I happen to use as wellA functional alternative (though not as safe) would be a
ref
access method, as proposed at #27062. It wouldn't be an elegant one-liner, but it would obviate the need for delegate allocation(s).Risks
This is a purely additive change, so it should have no risks on existing code.
The text was updated successfully, but these errors were encountered: