You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Prefer Dictionary.Remove(key, out value) over Dictionary.this[key], followed by Dictionary.Remove(key) #33800
Dictionary.ContainsKey<K, V(key), followed by Dictionary<K, V.this[key], followed by Dictionary<K, V>.Remove(key) can be combined into a single Remove call, using the overload accepting out TValue value.
// BeforepublicvoidRemoveValue(Dictionary<string,int>data,stringkey){
if(data.ContainsKey(key)){// Dictionary.ContainsKey<K, V(key),// followed by Dictionary<K, V.this[key],// followed by Dictionary<K, V>.Remove(key) can be combined into a single Remove call,// using the overload accepting out TValue value.Foo(data[key]);data.Remove(key);}}
// AfterpublicvoidRemoveValue(Dictionary<string,int>data,stringkey){
if(data.Remove(key,outintvalue)){Foo(value);}}
Applying the below example in the analyzer might be more complicated:
We came up with a lot of cases where the fixer can cause surprising functional changes, so this really only applies when there's an indexer followed by a call to Remove with no other method calls in between (because any method call could have modified the dictionary). As a specific example, in #33800 (comment) if Foo throws then in the before case the dictionary is not modified, but in the after case it is.
The case of x = dict[key]; dict.Remove(key); isn't safe to replace, because the exception is lost.
Conclusion:
If we find a dictionary call to TryGetValue that is immediately followed by a call to Remove (and the dictionary and the key are both simple variable or parameter expressions) then suggest collapsing them to Remove(key, out T). ("immediate" definitely means that there are no method calls or delegate invocations between those two expressions)
Thank you @steveberdy, sorry for the delayed response, it is assigned to you now, JFYI there are several analyzer proposals for dictionary, their implementations preferred to be written in one place (with different diagnostic ID when needed). I see only one of them merged into repo please try to add your implementation to that
Activity
jeffhandley commentedon Mar 21, 2020
Estimates:
carlossanlop commentedon Jan 8, 2021
This is closely related to #33797
Suggested severity: Info
Applying the below example in the analyzer might be more complicated:
We should also consider the case where the data is used multiple times, and when there's unrelated code in the way:
buyaa-n commentedon Jun 3, 2021
bartonjs commentedon Jul 27, 2021
Video
We came up with a lot of cases where the fixer can cause surprising functional changes, so this really only applies when there's an indexer followed by a call to Remove with no other method calls in between (because any method call could have modified the dictionary). As a specific example, in #33800 (comment) if
Foothrows then in the before case the dictionary is not modified, but in the after case it is.The case of
x = dict[key]; dict.Remove(key);isn't safe to replace, because the exception is lost.Conclusion:
If we find a dictionary call to TryGetValue that is immediately followed by a call to Remove (and the dictionary and the key are both simple variable or parameter expressions) then suggest collapsing them to Remove(key, out T). ("immediate" definitely means that there are no method calls or delegate invocations between those two expressions)
steveberdy commentedon Oct 15, 2021
@buyaa-n may I have this assigned to me? Thanks.
buyaa-n commentedon Oct 18, 2021
Thank you @steveberdy, sorry for the delayed response, it is assigned to you now, JFYI there are several analyzer proposals for dictionary, their implementations preferred to be written in one place (with different diagnostic ID when needed). I see only one of them merged into repo please try to add your implementation to that
steveberdy commentedon Sep 14, 2022
I'm sorry. I don't really have time to make this analyzer. I've unassigned myself.