CA2218: GetHashCode beim Überschreiben von Equals überschreiben.
Element | Wert |
---|---|
RuleId | CA2218 |
Category | Microsoft.Usage |
Unterbrechende Änderung | Nicht unterbrechend |
Ursache
Ein öffentlicher Typ überschreibt System.Object.Equals, jedoch nicht System.Object.GetHashCode.
Regelbeschreibung
GetHashCode gibt auf Grundlage der aktuellen Instanz einen Wert zurück, der für Hashalgorithmen und Datenstrukturen (z. B. eine Hashtabelle) geeignet ist. Zwei Objekte, die den gleichen Typ und Wert aufweisen, müssen auch den gleichen Hashcode zurückgeben. So wird sichergestellt, dass die Instanzen der folgenden Typen ordnungsgemäß funktionieren:
Typen, die System.Collections.Generic.IEqualityComparer<T> implementieren
Behandeln von Verstößen
Implementieren Sie eine Instanz von GetHashCode, um einen Verstoß gegen diese Regel zu korrigieren. Für ein Objektpaar mit dem gleichen Typ müssen Sie sicherstellen, dass die Implementierung denselben Wert zurückgibt, wenn Ihre Implementierung von Equals für das Paar true
zurückgibt.
Wann sollten Warnungen unterdrückt werden?
Unterdrücken Sie keine Warnung dieser Regel.
Beispiel für eine Klasse
Beschreibung
Das folgende Beispiel zeigt eine Klasse (Verweistyp), die gegen diese Regel verstößt.
Code
using System;
namespace Samples
{
// Violates this rule
public class 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 bool Equals(object obj)
{
if (obj == null)
return false;
if (GetType() != obj.GetType())
return false;
Point point = (Point)obj;
if (_X != point.X)
return false;
return _Y == point.Y;
}
}
}
Kommentare
Im folgenden Beispiel wird der Verstoß durch das Überschreiben von GetHashCode() korrigiert.
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);
}
}
}
Beispiel für eine Struktur
BESCHREIBUNG
Das folgende Beispiel zeigt eine Struktur (Werttyp), die gegen diese Regel verstößt.
Code
using System;
namespace Samples
{
// Violates this rule
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 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);
}
}
}
Kommentare
Im folgenden Beispiel wird der Verstoß durch das Überschreiben von GetHashCode() korrigiert.
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);
}
}
}
Ähnliche Regeln
CA1046: Gleichheitsoperator für Referenztypen nicht überladen.
CA2225: Operatorüberladungen weisen benannte Alternativen auf.
CA2226: Operatoren sollten symmetrische Überladungen aufweisen.
CA2224: Equals beim Überladen von Gleichheitsoperatoren überschreiben.
CA2231: Überladen Sie den Gleichheitsoperator beim Überschreiben von ValueType.Equals.
Siehe auch
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für