Condividi tramite


CA2218: Eseguire l'override di GetHashCode all'override di Equals

TypeName

OverrideGetHashCodeOnOverridingEquals

CheckId

CA2218

Category

Microsoft.Usage

Breaking Change

Non sostanziale

Causa

Un tipo pubblico esegue l'override di Object.Equals, ma non di Object.GetHashCode.

Descrizione della regola

Il metodo GetHashCode restituisce un valore, basato sull'istanza corrente, appropriato per algoritmi di hash e strutture di dati come una tabella hash. Due oggetti dello stesso tipo e uguali devono restituire lo stesso codice hash per assicurare il corretto funzionamento delle istanze dei tipi seguenti:

Come correggere le violazioni

Per correggere una violazione di questa regola, fornire un'implementazione di GetHashCode. Per una coppia di oggetti dello stesso tipo, è necessario assicurarsi che l'implementazione restituisca lo stesso valore se implementazione di Equals restituisce true per la coppia.

Esclusione di avvisi

Non escludere un avviso da questa regola.

Esempio di classe

Oggetto di descrizione

Nell'esempio riportato di seguito viene illustrata una classe (tipo di riferimento) che viola questa regola.

Codice

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

Commenti

Nell'esempio seguente viene corretta la violazione eseguendo l'override di GetHashCode.

Codice

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

Esempio di struttura

Oggetto di descrizione

Nell'esempio riportato di seguito viene mostrata una struttura (tipo di valore) che viola questa regola.

Codice

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

Commenti

Nell'esempio seguente viene corretta la violazione eseguendo l'override di GetHashCode.

Codice

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

Regole correlate

CA1046: Non eseguire l'overload dell'operatore "uguale a" per i tipi di riferimento

CA2225: Gli overload degli operatori hanno alternative con nome

CA2226: Gli operatori devono avere overload simmetrici

CA2224: Eseguire l'override di Equals all'override dell'operatore

CA2231: Eseguire l'overload dell'operatore "uguale a" all'override di ValueType.Equals

Vedere anche

Riferimenti

Linee guida per l'implementazione del metodo Equals e dell'operatore di uguaglianza (==)

Object.Equals

Object.GetHashCode

HashTable