CA2218:覆寫 Equals 時必須一併覆寫 GetHashCode
型別名稱 |
OverrideGetHashCodeOnOverridingEquals |
CheckId |
CA2218 |
分類 |
Microsoft.Usage |
中斷變更 |
不中斷 |
原因
public 型別會覆寫 Object.Equals,但不會覆寫 Object.GetHashCode。
規則描述
GetHashCode 會依據目前執行個體 (Instance) 傳回值,適用於雜湊演算法和資料結構,如雜湊資料表。兩個型別相同且相等的物件必須傳回相同的雜湊程式碼,才能確保下列型別的執行個體運作正常。
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 (==)