CA2218:覆寫 Equals 時必須一併覆寫 GetHashCode
型別名稱 |
OverrideGetHashCodeOnOverridingEquals |
CheckId |
CA2218 |
分類 |
Microsoft.Usage |
中斷變更 |
不中斷 |
原因
public 型別會覆寫 Object.Equals,但不會覆寫 Object.GetHashCode。
規則描述
GetHashCode 會依據目前執行個體 (Instance) 傳回值,適用於雜湊演算法和資料結構,如雜湊資料表。 兩個型別相同且相等的物件必須傳回相同的雜湊程式碼,才能確保下列型別的執行個體運作正常。
HashTable
Dictionary
SortDictionary
SortList
HybredDictionary
實作 IEqualityComparer 的型別
如何修正違規
若要修正違反此規則的情形,請提供 GetHashCode 的實作。 對於一組相同型別的物件,如果 Equals 的實作會針對這組物件傳回 true,則您必須確定實作會傳回相同值。
隱藏警告的時機
請勿隱藏此規則的警告。
類別範例
描述
下列範例顯示違反此規則的類別 (參考型別)。
程式碼
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;
}
}
}
註解
下列範例藉由覆寫 GetHashCode 修正違規。
程式碼
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);
}
}
}
結構範例
描述
下列範例顯示違反此規則的結構 (實值型別)。
程式碼
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);
}
}
}
註解
下列範例藉由覆寫 GetHashCode 修正違規。
程式碼
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);
}
}
}
相關規則
CA2224:多載等號比較運算子時必須一併覆寫 Equals
CA2231:覆寫 ValueType.Equals 時必須一併多載等號比較運算子
請參閱
參考
Guidelines for Implementing Equals and the Equality Operator (==)
HashTable