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.