CA2218: GetHashCode beim Überschreiben von Equals überschreiben.

Element Wert
RuleId CA2218
Category Microsoft.Usage
Unterbrechende Änderung Nicht unterbrechend

Ursache

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

Regelbeschreibung

GetHashCode gibt auf Grundlage der aktuellen Instanz einen Wert zurück, der für Hashalgorithmen und Datenstrukturen (z. B. eine Hashtabelle) geeignet ist. Zwei Objekte, die den gleichen Typ und Wert aufweisen, müssen auch den gleichen Hashcode zurückgeben. So wird sichergestellt, dass die Instanzen der folgenden Typen ordnungsgemäß funktionieren:

Behandeln von Verstößen

Implementieren Sie eine Instanz von GetHashCode, um einen Verstoß gegen diese Regel zu korrigieren. Für ein Objektpaar mit dem gleichen Typ müssen Sie sicherstellen, dass die Implementierung denselben Wert zurückgibt, wenn Ihre Implementierung von Equals für das Paar true zurückgibt.

Wann sollten Warnungen unterdrückt werden?

Unterdrücken Sie keine Warnung dieser Regel.

Beispiel für eine Klasse

Beschreibung

Das folgende Beispiel zeigt eine Klasse (Verweistyp), 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;        
        }    
    }
}

Kommentare

Im folgenden Beispiel wird der Verstoß durch das Überschreiben von GetHashCode() korrigiert.

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

Beispiel für eine Struktur

BESCHREIBUNG

Das folgende Beispiel zeigt eine Struktur (Werttyp), 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);        
        }    
    }
}

Kommentare

Im folgenden Beispiel wird der Verstoß durch das Überschreiben von GetHashCode() korrigiert.

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

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