From 71e7895241760e760752584ce10a874149357d45 Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Fri, 30 Jun 2023 12:37:06 +0200 Subject: [PATCH 1/4] Add documentation for CA1864. --- .../code-analysis/quality-rules/ca1864.md | 94 +++++++++++++++++++ .../code-analysis/quality-rules/index.md | 1 + .../quality-rules/performance-warnings.md | 1 + docs/navigate/tools-diagnostics/toc.yml | 12 ++- 4 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 docs/fundamentals/code-analysis/quality-rules/ca1864.md diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1864.md b/docs/fundamentals/code-analysis/quality-rules/ca1864.md new file mode 100644 index 0000000000000..51bde8d850e02 --- /dev/null +++ b/docs/fundamentals/code-analysis/quality-rules/ca1864.md @@ -0,0 +1,94 @@ +--- +title: "CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method" +description: "Learn about code analyzer rule CA1864 - Prefer the 'IDictionary.TryAdd(TKey, TValue)' method" +ms.date: 06/30/2023 +ms.topic: reference +f1_keywords: + - CA1864 + - PreferDictionaryTryMethodsOverContainsKeyGuardAnalyzer +helpviewer_keywords: + - CA1864 +dev_langs: + - CSharp + - VB +--- + +# CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method + +| | Value | +| ----------------------------------- |----------------------------------------| +| **Rule ID** | CA1864 | +| **Category** | [Performance](performance-warnings.md) | +| **Fix is breaking or non-breaking** | Non-breaking | +| **Enabled by default in .NET 7** | No | + +## Cause + + is guarded by on a call. + +## Rule description + +Both and perform a lookup of the value. also throws an exception if the key is already present in the dictionary. It is more efficient to call which will return a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. + +## How to fix violations + +Replace a call to followed by with a call to . + +## Example + +The following code snippet shows a violation of CA1864: + +```csharp +void Run(IDictionary dictionary) +{ + if(!dictionary.ContainsKey(2)) { + dictionary.Add(2, "Hello World"); + } +} +``` + +```vb +Sub Run(dictionary As IDictionary(Of Integer, String)) + If Not dictionary.ContainsKey(2) Then + dictionary.Add(2, "Hello World") + End If +End Sub +``` + +The following code snippet fixes the violation: + +```csharp +void Run(IDictionary dictionary) +{ + dictionary.TryAdd(2, "Hello World"); +} +``` + +```vb +Sub Run(dictionary As IDictionary(Of Integer, String)) + dictionary.TryAdd(2, "Hello World") +End Sub +``` + +## When to suppress warnings + +It's safe to suppress this warning if performance isn't a concern and when the exception potentially thrown by is caught. + +## Suppress a warning + +If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule. + +```csharp +#pragma warning disable CA1864 +// The code that's violating the rule is on this line. +#pragma warning restore CA1864 +``` + +To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md). + +```ini +[*.{cs,vb}] +dotnet_diagnostic.CA1864.severity = none +``` + +For more information, see [How to suppress code analysis warnings](../suppress-warnings.md). diff --git a/docs/fundamentals/code-analysis/quality-rules/index.md b/docs/fundamentals/code-analysis/quality-rules/index.md index fee43d711500a..b2f340e507c35 100644 --- a/docs/fundamentals/code-analysis/quality-rules/index.md +++ b/docs/fundamentals/code-analysis/quality-rules/index.md @@ -157,6 +157,7 @@ The following table lists code quality analysis rules. > | [CA1859: Use concrete types when possible for improved performance](ca1859.md) | Code uses interface types or abstract types, leading to unnecessary interface calls or virtual calls. | > | [CA1860: Avoid using 'Enumerable.Any()' extension method](ca1860.md) | It's more efficient and clearer to use `Length`, `Count`, or `IsEmpty` (if possible) than to call to determine whether a collection type has any elements. | > | [CA1861: Avoid constant arrays as arguments](ca1861.md) | Constant arrays passed as arguments are not reused which implies a performance overhead. Consider extracting them to 'static readonly' fields to improve performance. | +> | [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup of the value. also throws an exception if the key is already present in the dictionary. It is more efficient to call which will return a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. | > | [CA2000: Dispose objects before losing scope](ca2000.md) | Because an exceptional event might occur that will prevent the finalizer of an object from running, the object should be explicitly disposed before all references to it are out of scope. | > | [CA2002: Do not lock on objects with weak identity](ca2002.md) |An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object. | > | [CA2007: Do not directly await a Task](ca2007.md) | An asynchronous method [awaits](../../../csharp/language-reference/operators/await.md) a directly. When an asynchronous method awaits a directly, continuation occurs in the same thread that created the task. This behavior can be costly in terms of performance and can result in a deadlock on the UI thread. Consider calling to signal your intention for continuation. | diff --git a/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md b/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md index 7afc5ba045da5..6ff125cc765b4 100644 --- a/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md +++ b/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md @@ -70,3 +70,4 @@ Performance rules support high-performance libraries and applications. | [CA1859: Use concrete types when possible for improved performance](ca1859.md) | Code uses interface types or abstract types, leading to unnecessary interface calls or virtual calls. | | [CA1860: Avoid using 'Enumerable.Any()' extension method](ca1860.md) | It's more efficient and clearer to use `Length`, `Count`, or `IsEmpty` (if possible) than to call to determine whether a collection type has any elements. | | [CA1861: Avoid constant arrays as arguments](ca1861.md) | Constant arrays passed as arguments are not reused which implies a performance overhead. Consider extracting them to 'static readonly' fields to improve performance. | +| [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup of the value. also throws an exception if the key is already present in the dictionary. It is more efficient to call which will return a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. | diff --git a/docs/navigate/tools-diagnostics/toc.yml b/docs/navigate/tools-diagnostics/toc.yml index 11bdd74b19885..85568f211c4f3 100644 --- a/docs/navigate/tools-diagnostics/toc.yml +++ b/docs/navigate/tools-diagnostics/toc.yml @@ -349,7 +349,7 @@ items: - name: Specialized diagnostics items: - name: Overview - href: ../../core/diagnostics/specialized-diagnostics-overview.md + href: ../../core/diagnostics/specialized-diagnostics-overview.md - name: Event Source items: - name: Overview @@ -386,7 +386,7 @@ items: - name: Type-system events href: ../../fundamentals/diagnostics/runtime-type-events.md - name: Collect diagnostics in containers - href: ../../core/diagnostics/diagnostics-in-containers.md + href: ../../core/diagnostics/diagnostics-in-containers.md - name: Dumps items: - name: Overview @@ -401,9 +401,9 @@ items: - name: Collect dumps on crash href: ../../core/diagnostics/collect-dumps-crash.md - name: Symbols - href: ../../core/diagnostics/symbols.md + href: ../../core/diagnostics/symbols.md - name: EventPipe - href: ../../core/diagnostics/eventpipe.md + href: ../../core/diagnostics/eventpipe.md - name: Diagnostic port items: - name: Overview @@ -418,7 +418,7 @@ items: - name: DiagnosticSource and DiagnosticListener items: - name: Get started - href: ../../core/diagnostics/diagnosticsource-diagnosticlistener.md + href: ../../core/diagnostics/diagnosticsource-diagnosticlistener.md - name: .NET CLI global tools items: - name: Overview @@ -801,6 +801,8 @@ items: href: ../../fundamentals/code-analysis/quality-rules/ca1860.md - name: CA1861 href: ../../fundamentals/code-analysis/quality-rules/ca1861.md + - name: CA1864 + href: ../../fundamentals/code-analysis/quality-rules/ca1864.md - name: SingleFile rules items: - name: Overview From 98226d58167f9065dc35bd694a0fcae4c26b8ad3 Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Wed, 5 Jul 2023 15:30:27 +0200 Subject: [PATCH 2/4] Fix formatting --- docs/fundamentals/code-analysis/quality-rules/ca1864.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1864.md b/docs/fundamentals/code-analysis/quality-rules/ca1864.md index 51bde8d850e02..1e8d1d6274c2f 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca1864.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca1864.md @@ -28,7 +28,7 @@ dev_langs: ## Rule description -Both and perform a lookup of the value. also throws an exception if the key is already present in the dictionary. It is more efficient to call which will return a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. +Both and perform a lookup of the value. also throws an exception if the key is already present in the dictionary. It is more efficient to call which will return a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. ## How to fix violations From adfaf51dbf0bd458c4a1c8f06d6e89dbbb429d2d Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Thu, 6 Jul 2023 21:24:35 +0200 Subject: [PATCH 3/4] PR suggestions. --- docs/fundamentals/code-analysis/quality-rules/ca1864.md | 8 ++++---- docs/fundamentals/code-analysis/quality-rules/index.md | 2 +- .../code-analysis/quality-rules/performance-warnings.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1864.md b/docs/fundamentals/code-analysis/quality-rules/ca1864.md index 1e8d1d6274c2f..fdd2e5b28879f 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca1864.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca1864.md @@ -24,15 +24,15 @@ dev_langs: ## Cause - is guarded by on a call. + is guarded by a call. ## Rule description -Both and perform a lookup of the value. also throws an exception if the key is already present in the dictionary. It is more efficient to call which will return a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. +Both and perform a lookup, which is redundant. also throws an exception if the key is already present in the dictionary. It's more efficient to call , which returns a Boolean value that indicates if the value was added or not. `TryAdd` doesn't override the key's value if the key is already present. ## How to fix violations -Replace a call to followed by with a call to . +Replace a call to that's followed by a call to with a single call to . ## Example @@ -72,7 +72,7 @@ End Sub ## When to suppress warnings -It's safe to suppress this warning if performance isn't a concern and when the exception potentially thrown by is caught. +It's safe to suppress this warning if performance isn't a concern and if you handle the exception that might be thrown by . ## Suppress a warning diff --git a/docs/fundamentals/code-analysis/quality-rules/index.md b/docs/fundamentals/code-analysis/quality-rules/index.md index b2f340e507c35..39bcfa68fffcf 100644 --- a/docs/fundamentals/code-analysis/quality-rules/index.md +++ b/docs/fundamentals/code-analysis/quality-rules/index.md @@ -157,7 +157,7 @@ The following table lists code quality analysis rules. > | [CA1859: Use concrete types when possible for improved performance](ca1859.md) | Code uses interface types or abstract types, leading to unnecessary interface calls or virtual calls. | > | [CA1860: Avoid using 'Enumerable.Any()' extension method](ca1860.md) | It's more efficient and clearer to use `Length`, `Count`, or `IsEmpty` (if possible) than to call to determine whether a collection type has any elements. | > | [CA1861: Avoid constant arrays as arguments](ca1861.md) | Constant arrays passed as arguments are not reused which implies a performance overhead. Consider extracting them to 'static readonly' fields to improve performance. | -> | [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup of the value. also throws an exception if the key is already present in the dictionary. It is more efficient to call which will return a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. | +> | [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup, which is redundant. It's is more efficient to call , which returns a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. | > | [CA2000: Dispose objects before losing scope](ca2000.md) | Because an exceptional event might occur that will prevent the finalizer of an object from running, the object should be explicitly disposed before all references to it are out of scope. | > | [CA2002: Do not lock on objects with weak identity](ca2002.md) |An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object. | > | [CA2007: Do not directly await a Task](ca2007.md) | An asynchronous method [awaits](../../../csharp/language-reference/operators/await.md) a directly. When an asynchronous method awaits a directly, continuation occurs in the same thread that created the task. This behavior can be costly in terms of performance and can result in a deadlock on the UI thread. Consider calling to signal your intention for continuation. | diff --git a/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md b/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md index 6ff125cc765b4..a74890d73f373 100644 --- a/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md +++ b/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md @@ -70,4 +70,4 @@ Performance rules support high-performance libraries and applications. | [CA1859: Use concrete types when possible for improved performance](ca1859.md) | Code uses interface types or abstract types, leading to unnecessary interface calls or virtual calls. | | [CA1860: Avoid using 'Enumerable.Any()' extension method](ca1860.md) | It's more efficient and clearer to use `Length`, `Count`, or `IsEmpty` (if possible) than to call to determine whether a collection type has any elements. | | [CA1861: Avoid constant arrays as arguments](ca1861.md) | Constant arrays passed as arguments are not reused which implies a performance overhead. Consider extracting them to 'static readonly' fields to improve performance. | -| [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup of the value. also throws an exception if the key is already present in the dictionary. It is more efficient to call which will return a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. | +| [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup, which is redundant. It's is more efficient to call , which returns a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. | From 74663fa0c19857140a1a57a30c52920e474bee8b Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Fri, 7 Jul 2023 16:52:32 +0200 Subject: [PATCH 4/4] PR suggestions --- docs/fundamentals/code-analysis/quality-rules/ca1864.md | 2 +- docs/fundamentals/code-analysis/quality-rules/index.md | 2 +- .../code-analysis/quality-rules/performance-warnings.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1864.md b/docs/fundamentals/code-analysis/quality-rules/ca1864.md index fdd2e5b28879f..92fbc4993bc5d 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca1864.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca1864.md @@ -28,7 +28,7 @@ dev_langs: ## Rule description -Both and perform a lookup, which is redundant. also throws an exception if the key is already present in the dictionary. It's more efficient to call , which returns a Boolean value that indicates if the value was added or not. `TryAdd` doesn't override the key's value if the key is already present. +Both and perform a lookup, which is redundant. also throws an exception if the key is already present in the dictionary. It's more efficient to call , which returns a Boolean value that indicates if the value was added or not. `TryAdd` doesn't overwrite the key's value if the key is already present. ## How to fix violations diff --git a/docs/fundamentals/code-analysis/quality-rules/index.md b/docs/fundamentals/code-analysis/quality-rules/index.md index 39bcfa68fffcf..46d5fdc02325d 100644 --- a/docs/fundamentals/code-analysis/quality-rules/index.md +++ b/docs/fundamentals/code-analysis/quality-rules/index.md @@ -157,7 +157,7 @@ The following table lists code quality analysis rules. > | [CA1859: Use concrete types when possible for improved performance](ca1859.md) | Code uses interface types or abstract types, leading to unnecessary interface calls or virtual calls. | > | [CA1860: Avoid using 'Enumerable.Any()' extension method](ca1860.md) | It's more efficient and clearer to use `Length`, `Count`, or `IsEmpty` (if possible) than to call to determine whether a collection type has any elements. | > | [CA1861: Avoid constant arrays as arguments](ca1861.md) | Constant arrays passed as arguments are not reused which implies a performance overhead. Consider extracting them to 'static readonly' fields to improve performance. | -> | [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup, which is redundant. It's is more efficient to call , which returns a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. | +> | [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup, which is redundant. It's is more efficient to call , which returns a `bool` indicating if the value was added or not. `TryAdd` doesn't overwrite the key's value if the key is already present. | > | [CA2000: Dispose objects before losing scope](ca2000.md) | Because an exceptional event might occur that will prevent the finalizer of an object from running, the object should be explicitly disposed before all references to it are out of scope. | > | [CA2002: Do not lock on objects with weak identity](ca2002.md) |An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object. | > | [CA2007: Do not directly await a Task](ca2007.md) | An asynchronous method [awaits](../../../csharp/language-reference/operators/await.md) a directly. When an asynchronous method awaits a directly, continuation occurs in the same thread that created the task. This behavior can be costly in terms of performance and can result in a deadlock on the UI thread. Consider calling to signal your intention for continuation. | diff --git a/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md b/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md index a74890d73f373..385d3927b7df2 100644 --- a/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md +++ b/docs/fundamentals/code-analysis/quality-rules/performance-warnings.md @@ -70,4 +70,4 @@ Performance rules support high-performance libraries and applications. | [CA1859: Use concrete types when possible for improved performance](ca1859.md) | Code uses interface types or abstract types, leading to unnecessary interface calls or virtual calls. | | [CA1860: Avoid using 'Enumerable.Any()' extension method](ca1860.md) | It's more efficient and clearer to use `Length`, `Count`, or `IsEmpty` (if possible) than to call to determine whether a collection type has any elements. | | [CA1861: Avoid constant arrays as arguments](ca1861.md) | Constant arrays passed as arguments are not reused which implies a performance overhead. Consider extracting them to 'static readonly' fields to improve performance. | -| [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup, which is redundant. It's is more efficient to call , which returns a `bool` indicating if the value was added or not. It will not override the key's value if the key is already present. | +| [CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method](ca1864.md) | Both and perform a lookup, which is redundant. It's is more efficient to call , which returns a `bool` indicating if the value was added or not. `TryAdd` doesn't overwrite the key's value if the key is already present. |