CA1868: Unnecessary call to 'Contains' for sets
Property | Value |
---|---|
Rule ID | CA1868 |
Title | Unnecessary call to 'Contains' for sets |
Category | Performance |
Fix is breaking or non-breaking | Non-breaking |
Enabled by default in .NET 8 | As suggestion |
Cause
An ISet<T>.Add or ICollection<T>.Remove call is guarded by a call to Contains. Or, an IImmutableSet<T>.Add or IImmutableSet<T>.Remove call is guarded by a call to IImmutableSet<T>.Contains.
Rule description
Both ISet<T>.Add(T) and ICollection<T>.Remove(T) perform a lookup, which makes it redundant to call ICollection<T>.Contains(T) beforehand. It's more efficient to call Add(T) or Remove(T) directly, which returns a Boolean value indicating whether the item was added or removed.
This logic also applies to IImmutableSet<T>.Add(T) and IImmutableSet<T>.Remove(T), except that they either return a new set if the item is added or removed, or the original set if it wasn't.
How to fix violations
Replace the call to ICollection<T>.Contains(T) (or IImmutableSet<T>.Contains(T)) that's followed by a call to ISet<T>.Add(T) or ICollection<T>.Remove(T) (or IImmutableSet<T>.Add(T) or IImmutableSet<T>.Remove(T)) with a single call to the latter method.
Example
The following code snippet shows a violation of CA1868:
void Run(ISet<string> set)
{
if (!set.Contains("Hello World"))
{
set.Add("Hello World");
}
}
Sub Run(set As ISet(Of String))
If Not set.Contains("Hello World") Then
set.Add("Hello World")
End If
End Sub
The following code snippet fixes the violation:
void Run(ISet<string> set)
{
set.Add("Hello World");
}
Sub Run(set As ISet(Of String))
set.Add("Hello World")
End Sub
When to suppress warnings
It's safe to suppress this warning if performance isn't a concern.
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.
#pragma warning disable CA1868
// The code that's violating the rule is on this line.
#pragma warning restore CA1868
To disable the rule for a file, folder, or project, set its severity to none
in the configuration file.
[*.{cs,vb}]
dotnet_diagnostic.CA1868.severity = none
For more information, see How to suppress code analysis warnings.