CA2218: Přepište GetHashCode při přepsání Equals

Zboží Hodnota
RuleId CA2218
Kategorie Microsoft.Usage
Změna způsobující chybu Nenarušující

Příčina

Veřejný typ přepisuje System.Object.Equals , ale nepřepíše System.Object.GetHashCode.

Popis pravidla

GetHashCode vrátí hodnotu založenou na aktuální instanci, která je vhodná pro algoritmy hash a datové struktury, jako je například tabulka hash. Dva objekty, které jsou stejného typu a jsou stejné, musí vrátit stejný hash kód, aby instance následujících typů fungovaly správně:

Jak opravit porušení

Chcete-li opravit porušení tohoto pravidla, poskytněte implementaci GetHashCode. Pro dvojici objektů stejného typu je nutné zajistit, aby implementace vrátila stejnou hodnotu, pokud vaše implementace Equals vrací pro dvojici.true

Kdy potlačit upozornění

Nepotlačujte upozornění na toto pravidlo.

Příklad třídy

Popis

Následující příklad ukazuje třídu (typ odkazu), která porušuje toto pravidlo.

Kód

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

Poznámky

Následující příklad opravuje porušení přepsáním GetHashCode().

Kód

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

Příklad struktury

Popis

Následující příklad ukazuje strukturu (typ hodnoty), která porušuje toto pravidlo.

Kód

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

Poznámky

Následující příklad opravuje porušení přepsáním GetHashCode().

Kód

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: Nepřetěžujte operátory rovnosti na odkazových typech

CA2225: Přetížení operátoru mají pojmenované alternativy

CA2226: Operátory by měly mít symetrické přetížení

CA2224: Přepište Equals při přetížení operátoru rovnosti

CA2231: Přetižte operátor equals při přepsání ValueType.Equals

Viz také