CA1868: セットに対する 'Contains' の不要な呼び出し

プロパティ
ルール ID CA1868
Title セットに対する 'Contains' の不要な呼び出し
[カテゴリ] パフォーマンス
修正が中断ありか中断なしか なし
.NET 8 では既定で有効 提案として

原因

ISet<T>.Add または ICollection<T>.Remove の呼び出しは、Contains の呼び出しによってガードされます。 または、IImmutableSet<T>.Add または IImmutableSet<T>.Remove の呼び出しは、IImmutableSet<T>.Contains の呼び出しによってガードされます。

規則の説明

ISet<T>.Add(T)ICollection<T>.Remove(T) は両方とも検索を実行するため、ICollection<T>.Contains(T) の事前の呼び出しは冗長になります。 Add(T) または Remove(T) を直接呼び出すと、項目が追加されたか削除されたかを示すブール値が返されるため、より効率的です。

このロジックは、項目が追加または削除された場合に新しいセットを返すか、そうでない場合は元のセットを返す場合を除き、IImmutableSet<T>.Add(T)IImmutableSet<T>.Remove(T) にも適用されます。

違反の修正方法

ISet<T>.Add(T) または ICollection<T>.Remove(T) (または IImmutableSet<T>.Add(T) または IImmutableSet<T>.Remove(T)) の呼び出しが続く ICollection<T>.Contains(T) (または IImmutableSet<T>.Contains(T)) の呼び出しを、後のメソッドの 1 回の呼び出しに置き換えます。

次のコード スニペットは、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

次のコード スニペットでは違反を修正しています。

void Run(ISet<string> set)
{
    set.Add("Hello World");
}
Sub Run(set As ISet(Of String))
    set.Add("Hello World")
End Sub

どのようなときに警告を抑制するか

パフォーマンスが問題でない場合は、この警告を抑制しても問題ありません。

警告を抑制する

単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。

#pragma warning disable CA1868
// The code that's violating the rule is on this line.
#pragma warning restore CA1868

ファイル、フォルダー、またはプロジェクトの規則を無効にするには、構成ファイルでその重要度を none に設定します。

[*.{cs,vb}]
dotnet_diagnostic.CA1868.severity = none

詳細については、「コード分析の警告を抑制する方法」を参照してください。