CA2218: Přepište GetHashCode při přepsání Equals
TypeName |
OverrideGetHashCodeOnOverridingEquals |
CheckId |
CA2218 |
Kategorie |
Microsoft.Usage |
Narušující změna |
Nenarušující |
Příčina
Veřejný typ přepíše Object.Equals, ale nepřepíše Object.GetHashCode.
Popis pravidla
GetHashCode vrací hodnotu založenou na aktuální instanci, která je vhodná pro algoritmy hash a datové struktury, například tabulku hash.Dva objekty, které jsou stejného typu a jsou si rovny, musí vrátit stejný kód hash zajišťující správnou činnost instancí následujících typů:
Dictionary
SortDictionary
SortList
HybredDictionary
Typy, které implementují IEqualityComparer
Jak vyřešit porušení
K nápravě porušení tohoto pravidla implementujte GetHashCode.Pro dvojici objektů stejného typu je nutné zajistit, aby implementace vracela stejnou hodnotu, pokud implementace Equals vrací pro dvojici true.
Kdy potlačit upozornění
Nepotlačujte upozornění na toto pravidlo.
Příklad třídy
Description
Následující příklad ukazuje třídu (typ odkazu), která toto pravidlo porušuje.
Kód
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;
}
}
}
Komentáře
Následující příklad řeší porušení přepsáním GetHashCode.
Kód
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);
}
}
}
Příklad struktury
Description
Následující příklad ukazuje strukturu (typ hodnoty), která toto pravidlo porušuje.
Kód
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);
}
}
}
Komentáře
Následující příklad řeší porušení přepsáním GetHashCode.
Kód
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);
}
}
}
Související pravidla
CA1046: Nepřetěžujte operátory rovnosti na odkazových typech
CA2225: Přetížení operátoru mají pojmenované alternativy
CA2226: Operátory by měly mít symetrické přetížení
CA2224: Přepište Equals při přetížení operátoru rovnosti
CA2231: Přetižte operátor equals při přepsání ValueType.Equals
Viz také
Referenční dokumentace
Další zdroje
Guidelines for Implementing Equals and the Equality Operator (==)