CA2218: GetHashCode de substituição em substituição Equals
TypeName |
OverrideGetHashCodeOnOverridingEquals |
CheckId |
CA2218 |
<strong>Categoria</strong> |
Microsoft.Usage |
Alteração significativa |
Não separável |
Causa
Um tipo público substitui Object.Equals mas não substitui Object.GetHashCode.
Descrição da regra
GetHashCodeRetorna um valor, com base na instância atual, que é adequada para os algoritmos de hash e estruturas de dados como, por exemplo, uma tabela de hash.Dois objetos que são do mesmo tipo e são iguais devem retornar o mesmo código de hash para garantir que instâncias dos tipos a seguir funcionem corretamente:
HashTable
Dictionary
SortDictionary
SortList
HybredDictionary
Tipos que implementamIEqualityComparer
Como corrigir violações
Para corrigir uma violação desta regra, fornecer uma implementação de GetHashCode.Para um par de objetos do mesmo tipo, você deve garantir que a implementação retorna o mesmo valor se a implementação do Equals retorna true para o par.
Quando suprimir avisos
Não suprimir um aviso da regra.
Exemplo de classe
Descrição
O exemplo a seguir mostra uma classe (tipo de referência) que viola essa regra.
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;
}
}
}
Comentários
O exemplo a seguir corrige a violação, substituindo 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);
}
}
}
Exemplo de estrutura
Descrição
O exemplo a seguir mostra uma estrutura (tipo de valor) que viola essa regra.
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);
}
}
}
Comentários
O exemplo a seguir corrige a violação, substituindo 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);
}
}
}
Regras relacionadas
CA1046: Não sobrecarregar o operador equals em tipos de referência
CA2225: Sobrecargas operador nomeou alternativas
CA2226: Os operadores devem ter a sobrecargas simétricas
CA2224: É igual a substituição na sobrecarga de operador equals
CA2231: Sobrecarga de operador é igual a sobre a anulação de ValueType.Equals
Consulte também
Referência
Guidelines for Implementing Equals and the Equality Operator (==)
HashTable