Partager via


CA2218 : Remplacez GetHashCode au moment de remplacer Equals

TypeName

OverrideGetHashCodeOnOverridingEquals

CheckId

CA2218

Catégorie

Microsoft.Usage

Modification avec rupture

Modification sans rupture

Cause

Un type public substitue Object.Equals mais ne substitue pas Object.GetHashCode.

Description de la règle

GetHashCode retourne une valeur fondée sur l'instance actuelle adaptée aux algorithmes de hachage et aux structures de données telles qu'une table de hachage. Deux objets de même type et égaux doivent retourner le même code de hachage pour garantir le bon fonctionnement des types suivants :

Comment corriger les violations

Pour résoudre une violation de cette règle, fournissez une implémentation d' GetHashCode. Pour une paire d'objets de même type, vous devez garantir que l'implémentation retourne la même valeur si votre implémentation de Equals retourne true pour la paire.

Quand supprimer les avertissements

Ne supprimez aucun avertissement de cette règle.

Exemple de classe

Description

L'exemple suivant indique une classe (type référence) qui enfreint cette règle.

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

Commentaires

L'exemple suivant résout la violation en substituant GetHashCode.

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

Exemple de structure

Description

L'exemple suivant indique une structure (type valeur) qui enfreint cette règle.

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

Commentaires

L'exemple suivant résout la violation en substituant GetHashCode.

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

Règles connexes

CA1046 : Ne pas surcharger l'opérateur égal à sur les types référence

CA2225 : Les surcharges d'opérateur offrent d'autres méthodes nommées

CA2226 : Les opérateurs doivent contenir des surcharges symétriques

CA2224 : Remplacez Equals au moment de surcharger l'opérateur égal

CA2231 : Surchargez l'opérateur égal (equals) en remplaçant ValueType.Equals

Voir aussi

Référence

Instructions relatives à l'implémentation de Equals et de l'opérateur d'égalité (==)

Object.Equals

Object.GetHashCode

HashTable