Compartir a través de


CA2218: Reemplazar el método GetHashCode al reemplazar el método Equals

TypeName

OverrideGetHashCodeOnOverridingEquals

Identificador de comprobación

CA2218

Categoría

Microsoft.Usage

Cambio problemático

No

Motivo

Un tipo público reemplaza Object.Equals pero no reemplaza Object.GetHashCode.

Descripción de la regla

GetHashCode devuelve un valor basado en la instancia actual que se adapta para los algoritmos hash y a las estructuras de datos como una tabla hash.Dos objetos iguales y que son el mismo tipo deben devolver el mismo código hash para garantizar que las instancias de los tipos siguientes funcionan correctamente.

Cómo corregir infracciones

Para corregir una infracción de esta regla, proporcione una implementación de GetHashCode.Para obtener un par de objetos del mismo tipo, debe asegurarse de que la implementación devuelve el mismo valor si la implementación de Equals devuelve true para el par.

Cuándo suprimir advertencias

No suprima las advertencias de esta regla.

Ejemplo de clase

Descripción

En el siguiente ejemplo se muestra una clase (tipo de referencia) que infringe esta regla.

Código

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

Comentarios

El ejemplo siguiente corrige la infracción invalidando GetHashCode.

Código

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

Ejemplo de estructura

Descripción

En el siguiente ejemplo se muestra una estructura (tipo de valor) que infringe esta regla.

Código

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

Comentarios

El ejemplo siguiente corrige la infracción invalidando GetHashCode.

Código

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

Reglas relacionadas

CA1046: No sobrecargar el operador de igualdad en los tipos de referencia

CA2225: Las sobrecargas del operador tienen alternativas con nombre

CA2226: Los operadores deben tener sobrecargar simétricas

CA2224: Reemplazar Equals al sobrecargar operadores de igualdad

CA2231: Sobrecargar el operador de igualdad al reemplazar el tipo de valor de igualdad

Vea también

Referencia

Object.Equals

Object.GetHashCode

HashTable

Otros recursos

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