CA1815: Equals und Gleichheitsoperator für Werttypen überschreiben
TypeName |
OverrideEqualsAndOperatorEqualsOnValueTypes |
CheckId |
CA1815 |
Kategorie |
Microsoft.Performance |
Unterbrechende Änderung |
Nicht unterbrechend |
Ursache
Von einem öffentlichen Werttyp wird Object.Equals nicht überschrieben, bzw. der Gleichheitsoperator (==) wird nicht implementiert. Diese Regel überprüft keine Enumerationen.
Regelbeschreibung
Bei Werttypen wird die Reflection-Bibliothek von der geerbten Implementierung von Equals verwendet und der Inhalt aller Felder verglichen. Reflection ist rechenintensiv, und das Überprüfen eines jeden Felds auf Gleichheit ist eventuell unnötig. Wenn Sie erwarten, dass die Benutzer Instanzen vergleichen oder sortieren bzw. dass sie die Instanzen als Schlüssel für Hashtabellen verwenden, sollte der Werttyp Equals implementieren. Wenn die Programmiersprache das Überladen von Operatoren unterstützt, sollten Sie außerdem eine Implementierung der Gleichheits- und Ungleichheitsoperatoren bereitstellen.
Behandeln von Verstößen
Um einen Verstoß gegen diese Regel zu beheben, stellen Sie eine Implementierung von Equals bereit. Implementieren Sie den Gleichheitsoperator, falls dies möglich ist.
Wann sollten Warnungen unterdrückt werden?
Eine Warnung dieser Regel kann gefahrlos unterdrückt werden, wenn Instanzen des Werttyps nicht miteinander verglichen werden.
Beispiel für einen Verstoß
Beschreibungen
Im folgenden Beispiel wird eine Struktur (Werttyp) veranschaulicht, die gegen diese Regel verstößt.
Code
using System;
namespace Samples
{
// Violates this rule
public struct Point
{
private readonly int _X;
private readonly int _Y;
public Point(int x, int y)
{
_X = x;
_Y = y;
}
public int X
{
get { return _X; }
}
public int Y
{
get { return _Y; }
}
}
}
Beispiel für die Behandlung
Beschreibungen
Im folgenden Beispiel wird der vorherige Verstoß korrigiert, indem ValueTypeEquals() überschrieben und die Gleichheitsoperatoren (==, !=) implementiert werden.
Code
using System;
namespace Samples
{
public struct Point : IEquatable<Point>
{
private readonly int _X;
private readonly int _Y;
public Point(int x, int y)
{
_X = x;
_Y = y;
}
public int X
{
get { return _X; }
}
public int Y
{
get { return _Y; }
}
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);
}
}
}
Verwandte Regeln
CA2224: Equals beim Überladen von Gleichheitsoperatoren überschreiben
CA2231: Überladen Sie den Gleichheitsoperator beim Überschreiben von ValueType.Equals
CA2226: Operatoren sollten symmetrische Überladungen aufweisen