Udostępnij za pośrednictwem


CA2218: Zastąp GetHashCode przy zastępowaniu Equals

TypeName

OverrideGetHashCodeOnOverridingEquals

CheckId

CA2218

Kategoria

Microsoft.Usage

Zmiana kluczowa

Niekluczowa

Przyczyna

Typ publiczny zastępuje Object.Equals, lecz nie zastępuje Object.GetHashCode.

Opis reguły

GetHashCode zwraca wartość opartą na bieżącym wystąpieniu, które jest odpowiednie dla algorytmów wyznaczających wartości skrótu i struktur danych, takich jak tabela skrótów.Dwa obiekty, które są tego samego typu i są równe muszą zwrócić tę samą wartość skrótu, aby zapewnić prawidłowe działanie wystąpień poniższych typów:

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły, dostarcz implementację GetHashCode.Dla pary obiektów tego samego typu, należy zapewnić, że implementacja zwróci tę samą wartość, jeśli implementacja użytkownika Equals zwraca true dla tej pary.

Kiedy pominąć ostrzeżenia

Nie należy pomijać ostrzeżenia dotyczącego tej reguły.

Przykład klasy

Opis

Poniższy przykład pokazuje klasę (typ odwołania) naruszający tę regułę.

Kod

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

Komentarze

Poniższy przykład rozwiązuje naruszenie poprzez nadpisanie GetHashCode.

Kod

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

Przykład struktury

Opis

Poniższy przykład pokazuje strukturę (typ wartości) naruszający tę regułę.

Kod

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

Komentarze

Poniższy przykład rozwiązuje naruszenie poprzez nadpisanie GetHashCode.

Kod

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

Powiązane reguły

CA1046: Nie przeciążaj operatora equals w typach referencyjnych

CA2225: Operator overloads ma nazwanych zastępców

CA2226: Operatory powinny być przeciążane symetrycznie

CA2224: Zastąp metodę equals przeciążając operator equals

CA2231: Przeciąż operator equals przy zastępowaniu ValueType.Equals

Zobacz też

Informacje

Object.Equals

Object.GetHashCode

HashTable

Inne zasoby

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