CA2231:ValueType.Equals のオーバーライドで、演算子 equals をオーバーロードします

プロパティ
ルール ID CA2231
Title ValueType.Equals のオーバーライドで、演算子 equals をオーバーロードします
[カテゴリ] 使用方法
修正が中断ありか中断なしか なし
.NET 8 では既定で有効 提案として

原因

値型は、System.Object.Equals をオーバーライドしていますが、等値演算子を実装していません。

デフォルトでは、この規則の対象は外部から参照可能な型のみですが、これは構成可能です。

規則の説明

ほとんどのプログラミング言語では、値型に等値演算子 (==) の既定の実装はありません。 お使いのプログラミング言語が演算子のオーバーロードをサポートしている場合、等値演算子の実装を検討してください。 その動作は、Equals の動作と同じである必要があります。

等値演算子のオーバーロードされた実装では、既定の等値演算子を使用できません。 そうすると、スタック オーバーフローが発生します。 等値演算子を実装するには、実装で Object.Equals メソッドを使用します。 次に例を示します。

If (Object.ReferenceEquals(left, Nothing)) Then
    Return Object.ReferenceEquals(right, Nothing)
Else
    Return left.Equals(right)
End If
if (Object.ReferenceEquals(left, null))
    return Object.ReferenceEquals(right, null);
return left.Equals(right);

違反の修正方法

この規則違反を修正するには、等値演算子を実装します。

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

この規則による警告を抑制しても問題ありません。ただし、可能であれば等値演算子を指定することをお勧めします。

警告を抑制する

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

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

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

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

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

分析するコードを構成する

次のオプションを使用して、コードベースのどの部分に対してこの規則を実行するか構成します。

このオプションを構成できる対象は、この規則だけ、それを適用するすべての規則、それを適用するこのカテゴリ (使用方法) のすべての規則のいずれかです。 詳細については、「コード品質規則の構成オプション」を参照してください。

特定の API サーフェイスを含める

ユーザー補助に基づいて、この規則を実行するコードベースの部分を構成できます。 たとえば、非パブリック API サーフェイスでのみ規則を実行するように指定するには、プロジェクトの .editorconfig ファイルに次のキーと値のペアを追加します。

dotnet_code_quality.CAXXXX.api_surface = private, internal

次の例では、この規則に違反する型を定義します。

public struct PointWithoutHash
{
    private int x, y;

    public PointWithoutHash(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public override string ToString()
    {
        return String.Format("({0},{1})", x, y);
    }

    public int X { get { return x; } }

    public int Y { get { return x; } }

    // Violates rule: OverrideGetHashCodeOnOverridingEquals.
    // Violates rule: OverrideOperatorEqualsOnOverridingValueTypeEquals.
    public override bool Equals(object? obj)
    {
        if (obj?.GetType() != typeof(PointWithoutHash))
            return false;

        PointWithoutHash p = (PointWithoutHash)obj;
        return ((this.x == p.x) && (this.y == p.y));
    }
}

関連項目