Add MA0242: Use a value factory with ConcurrentDictionary.GetOrAdd/AddOrUpdate when the value is expensive - #1611
Merged
Conversation
…y is not in the ConcurrentDictionary ConcurrentDictionary.GetOrAdd(key, value) and AddOrUpdate(key, addValue, updateValueFactory) evaluate the value even when the key already exists. Report the values that are not cheap to evaluate and provide a code fix that wraps them in a value factory. Fixes #1610
meziantou
marked this pull request as ready for review
September 23, 2026 16:50
This was referenced Sep 23, 2026
Open
Bump Meziantou.Analyzer from 3.0.139 to 3.0.290
Analogy-LogViewer/Analogy.LogViewer.NLog.Targets#583
Open
Open
This was referenced Sep 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1610
What
New rule MA0242 (Performance, Info, enabled by default) with a code fix.
ConcurrentDictionary<TKey, TValue>.GetOrAdd(key, value)andAddOrUpdate(key, addValue, updateValueFactory)evaluate the value before the call, even when the key is already in the dictionary. The rule reports the value arguments that are not cheap to evaluate, and suggests the overloads taking aFunc<TKey, TValue>.await, struct creation with a user-defined constructor.this, fields, properties without arguments, array elements,default,typeof,sizeof, lambdas / method groups,throwexpressions, non-user-defined conversions, and built-in value-type operators /?:/??/?./ tuples whose operands are themselves cheap.Code fix
Wraps the expression in a lambda:
GetOrAdd(key, obj.ToString())→GetOrAdd(key, _ => obj.ToString()).value:/addValue:are renamed tovalueFactory:/addValueFactory:._is already in scope, the parameter is named_1,_2, ...await, ref structs,out varused after the call).Reviewer notes
obj.Name-style arguments.docs/Rules/MA0242.md.dotnet run --project src/DocumentationGeneratorproduces no further changes.