Freigeben über


CA2218: GetHashCode beim Überschreiben von Equals überschreiben

TypeName

OverrideGetHashCodeOnOverridingEquals

CheckId

CA2218

Kategorie

Microsoft.Usage

Unterbrechende Änderung

Nicht unterbrechend

Ursache

Ein öffentlicher Typ überschreibt Object.Equals, nicht jedoch Object.GetHashCode.

Regelbeschreibung

GetHashCode gibt einen Wert auf der Grundlage der aktuellen Instanz zurück, die sich für Hashalgorithmen und Datenstrukturen eignet, z. B. für eine Hashtabelle. Zwei Objekte, die den gleichen Typ aufweisen und gleich sind, müssen den gleichen Hashcode zurückgeben, damit sichergestellt ist, dass Instanzen der folgenden Typen einwandfrei arbeiten:

Behandeln von Verstößen

Um einen Verstoß gegen diese Regel zu beheben, stellen Sie eine Implementierung von GetHashCode bereit. Bei einem Paar von Objekten des gleichen Typs müssen Sie sicherstellen, dass die Implementierung den gleichen Wert zurückgibt, wenn die Implementierung von Equals für das Paar true zurückgibt.

Wann sollten Warnungen unterdrückt werden?

Unterdrücken Sie keine Warnung dieser Regel.

Klassenbeispiel

Beschreibungen

Im folgenden Beispiel wird eine Klasse (Referenztyp) veranschaulicht, die gegen diese Regel verstößt.

Code

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

Kommentar

Im folgenden Beispiel wird der Verstoß korrigiert, indem GetHashCode überschrieben wird.

Code

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

Strukturbeispiel

Beschreibungen

Im folgenden Beispiel wird eine Struktur (Werttyp) veranschaulicht, die gegen diese Regel verstößt.

Code

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

Kommentar

Im folgenden Beispiel wird der Verstoß korrigiert, indem GetHashCode überschrieben wird.

Code

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

Verwandte Regeln

CA1046: Gleichheitsoperator für Referenztypen nicht überladen

CA2225: Operatorüberladungen weisen benannte Alternativen auf

CA2226: Operatoren sollten symmetrische Überladungen aufweisen

CA2224: Equals beim Überladen von Gleichheitsoperatoren überschreiben

CA2231: Überladen Sie den Gleichheitsoperator beim Überschreiben von ValueType.Equals

Siehe auch

Referenz

Richtlinien für die Implementierung der Equals-Methode und des Gleichheitsoperators (==)

Object.Equals

Object.GetHashCode

HashTable