CA2218: Zastępowanie GetHashCode na zastępowanie równa się
TypeName |
OverrideGetHashCodeOnOverridingEquals |
CheckId |
CA2218 |
Kategoria |
Microsoft.Usage |
Zmiana kluczowa |
Niekluczowa |
Przyczyna
Typ publiczny zastępuje Object.Equals, lecz nie zastępuje Object.GetHashCode.
Opis reguły
GetHashCode zwraca wartość opartą na bieżącym wystąpieniu, które jest odpowiednie dla algorytmów wyznaczających wartości skrótu i struktur danych, takich jak tabela skrótów.Dwa obiekty, które są tego samego typu i są równe muszą zwrócić tę samą wartość skrótu, aby zapewnić prawidłowe działanie wystąpień poniższych typów:
HashTable
Dictionary
SortDictionary
SortList
HybredDictionary
Typy implementujące IEqualityComparer
Jak naprawić naruszenia
Aby naprawić naruszenie tej reguły, dostarcz implementację GetHashCode.Dla pary obiektów tego samego typu, należy zapewnić, że implementacja zwróci tę samą wartość, jeśli implementacja użytkownika Equals zwraca true dla tej pary.
Kiedy pominąć ostrzeżenia
Nie należy pomijać ostrzeżenia dotyczącego tej reguły.
Przykład klasy
Opis
Poniższy przykład pokazuje klasę (typ odwołania) naruszający tę regułę.
Kod
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;
}
}
}
Komentarze
Poniższy przykład rozwiązuje naruszenie poprzez nadpisanie GetHashCode.
Kod
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);
}
}
}
Przykład struktury
Opis
Poniższy przykład pokazuje strukturę (typ wartości) naruszający tę regułę.
Kod
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);
}
}
}
Komentarze
Poniższy przykład rozwiązuje naruszenie poprzez nadpisanie GetHashCode.
Kod
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);
}
}
}
Powiązane reguły
CA1046: Nie obciążając operator równości na typy odwołań
CA2225: Operator overloads nazwaną zastępcy
CA2226: Podmioty gospodarcze powinny mieć overloads symetryczne
CA2224: Zastępowanie jest równe na przeciążanie operatora równości
CA2231: Operator przeciążenie jest równe na przesłanianie ValueType.Equals
Zobacz też
Informacje
Guidelines for Implementing Equals and the Equality Operator (==)
HashTable