共用方式為


覆寫 Equals 時必須一併覆寫 GetHashCode

更新:2007 年 11 月

型別名稱

OverrideGetHashCodeOnOverridingEquals

CheckId

CA2218

分類

Microsoft.Usage

中斷變更

非中斷

原因

public 型別會覆寫 Object.Equals,但不會覆寫 Object.GetHashCode

規則描述

GetHashCode 會依據目前執行個體 (Instance) 傳回值,適用於雜湊演算法和資料結構,如雜湊資料表。兩個型別相同且相等的物件必須傳回相同的雜湊程式碼,才能確保下列型別的執行個體運作正常。

如何修正違規

若要修正違反此規則的情形,請提供 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);        
        }    
    }
}

相關規則

請勿多載參考型別上的等號比較運算子

運算子多載必須有具名的替代方法

運算子應該有對稱的多載

多載等號比較運算子時必須一併覆寫 Equals

覆寫 ValueType.Equals 時必須一併多載等號比較運算子

請參閱

參考

實作 Equals 和相等運算子 (==) 的方針

Object.Equals

Object.GetHashCode

HashTable