CA2218: Invalidar el método GetHashCode al invalidar el método Equals
Elemento | Valor |
---|---|
RuleId | CA2218 |
Category | Microsoft.Usage |
Cambio importante | Poco problemático |
Causa
Un tipo público invalida System.Object.Equals, pero no System.Object.GetHashCode.
Descripción de la regla
GetHashCode devuelve un valor basado en la instancia actual que es adecuado para los algoritmos hash y las estructuras de datos como una tabla hash. Dos objetos que son del mismo tipo y son iguales deben devolver el mismo código hash para garantizar que las instancias de los tipos siguientes funcionen correctamente:
Tipos que implementan System.Collections.Generic.IEqualityComparer<T>
Cómo corregir infracciones
Para corregir una infracción de esta regla, proporcione una implementación de GetHashCode. Para un par de objetos del mismo tipo, debe asegurarse de que la implementación devuelva el mismo valor si la implementación de Equals devuelve true
para el par.
Cuándo suprimir las advertencias
No suprima las advertencias de esta regla.
Ejemplo de clase
Descripción
En el ejemplo siguiente 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
En el ejemplo siguiente se corrige la infracción mediante el reemplazo de 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 ejemplo siguiente 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
En el ejemplo siguiente se corrige la infracción mediante el reemplazo de 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 sobrecargas simétricas
CA2224: Invalidar Equals al sobrecargar operadores de igualdad
CA2231: Sobrecargar el operador equals al invalidar ValueType.Equals
Vea también
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de