共用方式為


CA2218:覆寫 Equals 時必須一併覆寫 GetHashCode

型別名稱

OverrideGetHashCodeOnOverridingEquals

CheckId

CA2218

分類

Microsoft.Usage

中斷變更

不中斷

原因

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

規則描述

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

如何修正違規

若要修正違反此規則的情形,請提供 GetHashCode 的實作。 對於一組相同型別的物件,如果 Equals 的實作會針對這組物件傳回 true,則您必須確定實作會傳回相同值。

隱藏警告的時機

請勿隱藏此規則的警告。

類別範例

ms182358.collapse_all(zh-tw,VS.110).gif描述

下列範例顯示違反此規則的類別 (參考型別)。

ms182358.collapse_all(zh-tw,VS.110).gif程式碼

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;        
        }    
    }
}

ms182358.collapse_all(zh-tw,VS.110).gif註解

下列範例藉由覆寫 GetHashCode 修正違規。

ms182358.collapse_all(zh-tw,VS.110).gif程式碼

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);        
        }    
    }
}

結構範例

ms182358.collapse_all(zh-tw,VS.110).gif描述

下列範例顯示違反此規則的結構 (實值型別)。

ms182358.collapse_all(zh-tw,VS.110).gif程式碼

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);        
        }    
    }
}

ms182358.collapse_all(zh-tw,VS.110).gif註解

下列範例藉由覆寫 GetHashCode 修正違規。

ms182358.collapse_all(zh-tw,VS.110).gif程式碼

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);        
        }    
    }
}

相關規則

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

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

CA2226:運算子應該有對稱的多載

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

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

請參閱

參考

Guidelines for Implementing Equals and the Equality Operator (==)

Object.Equals

Object.GetHashCode

HashTable