CA1815: Equals und Gleichheitsoperator für Werttypen überschreiben.

Eigenschaft Wert
Regel-ID CA1815
Titel Equals und Gleichheitsoperator für Werttypen überschreiben.
Kategorie Leistung
Fix führt oder führt nicht zur Unterbrechung Nicht unterbrechend
Standardmäßig in .NET 8 aktiviert Nein

Ursache

Ein Werttyp überschreibt System.Object.Equals nicht oder implementiert nicht den Gleichheitsoperator (==). Diese Regel überprüft keine Enumerationen.

Standardmäßig werden mit dieser Regel nur extern sichtbare Typen überprüft, aber dies ist konfigurierbar.

Regelbeschreibung

Bei nicht für Blitting geeigneten Werttypen verwendet die geerbte Implementierung von Equals die Bibliothek System.Reflection, um den Inhalt aller Felder zu vergleichen. Reflection ist rechenintensiv, und das Überprüfen eines jeden Felds auf Gleichheit ist eventuell unnötig. Wenn Sie erwarten, dass die Benutzer Instanzen vergleichen, sortieren oder als Schlüssel für Hashtabellen verwenden, sollte der Werttyp Equals implementieren. Wenn Ihre Programmiersprache Operatorüberladung unterstützt, sollten Sie ebenso eine Implementierung der Gleichheits- und Ungleichheitsoperatoren bereitstellen.

Behandeln von Verstößen

Implementieren Sie eine Instanz von Equals, um einen Verstoß gegen diese Regel zu korrigieren. Implementieren Sie nach Möglichkeit den Gleichheitsoperator.

Wann sollten Warnungen unterdrückt werden?

Warnungen für diese Regel können bedenkenlos unterdrückt werden, wenn die Instanzen des Werttyps nicht miteinander verglichen werden.

Unterdrücken einer Warnung

Um nur eine einzelne Verletzung zu unterdrücken, fügen Sie der Quelldatei Präprozessoranweisungen hinzu, um die Regel zu deaktivieren und dann wieder zu aktivieren.

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

Um die Regel für eine Datei, einen Ordner oder ein Projekt zu deaktivieren, legen Sie den Schweregrad in der Konfigurationsdatei auf none fest.

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

Weitere Informationen finden Sie unter Vorgehensweise: Unterdrücken von Codeanalyse-Warnungen.

Konfigurieren des zu analysierenden Codes

Mithilfe der folgenden Option können Sie konfigurieren, für welche Teile Ihrer Codebasis diese Regel ausgeführt werden soll.

Sie können diese Option nur für diese Regel, für alle zutreffenden Regeln oder für alle zutreffenden Regeln in dieser Kategorie (Leistung) konfigurieren. Weitere Informationen finden Sie unter Konfigurationsoptionen für die Codequalitätsregel.

Einschließen bestimmter API-Oberflächen

Sie können je nach Zugänglichkeit festlegen, für welche Bestandteile Ihrer Codebasis diese Regel ausgeführt wird. Sie können beispielsweise festlegen, dass die Regel nur für die nicht öffentliche API-Oberfläche ausgeführt werden soll, indem Sie einer EDITORCONFIG-Datei in Ihrem Projekt das folgende Schlüssel-Wert-Paar hinzufügen:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Beispiel

Der folgende Code zeigt eine Struktur (Werttyp), die gegen diese Regel verstößt:

// Violates this rule
public struct Point
{
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X { get; }

    public int Y { get; }
}

Dieser Code korrigiert den vorangehenden Verstoß, indem System.ValueType.Equals überschrieben wird und die Gleichheitsoperatoren == und != implementiert werden:

public struct Point : IEquatable<Point>
{
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X { get; }

    public int Y { get; }

    public override int GetHashCode()
    {
        return X ^ Y;
    }

    public override bool Equals(object? obj)
    {
        if (!(obj is Point))
            return false;

        return Equals((Point)obj);
    }

    public bool Equals(Point other)
    {
        if (X != other.X)
            return false;

        return Y == other.Y;
    }

    public static bool operator ==(Point point1, Point point2)
    {
        return point1.Equals(point2);
    }

    public static bool operator !=(Point point1, Point point2)
    {
        return !point1.Equals(point2);
    }
}

Siehe auch