Implementing the Equals Method
Para obter informações sobre como implementar o operador de igualdade (= =), consulte diretrizes para o operador de igualdade (= =) e a implementação é igual a.
Substituir o GetHashCode método para permitir que um tipo de funcionar corretamente em uma tabela de hash.
Não jogue uma exceção na implementação de um é igual a método. Em vez disso, retornar false para um argumento nulo.
Siga o contract definido na O método de Object. Equals da seguinte maneira:
x.Equals(x)Retorna true.
x.Equals(y)Retorna o mesmo valor de y.Equals(x).
(x.Equals(y) && y.Equals(z))Retorna true se x.Equals(z) retorna true.
Invocações sucessivas de x.Equals(y) retornar o mesmo valor, como os objetos referenciados por x e y não são modificados.
x.Equals(null)Retorna false.
Para alguns tipos de objetos, é desejável que é igual a testar igualdade de valor em vez de igualdade referencial. Tais implementações de é igual a retornar true se os dois objetos terá o mesmo valor, mesmo que não estejam na mesma instância. A definição do que constitui o valor de um objeto é o implementador do tipo, mas é normalmente alguns ou todos os dados armazenados em variáveis de instância do objeto. Por exemplo, o valor de uma seqüência de caracteres é baseado nos caracteres da seqüência de caracteres; o é igual a método o seqüência classe retorna true para quaisquer duas instâncias de uma seqüência de caracteres que contêm os mesmos caracteres na mesma ordem.
Quando o é igual a método de uma classe base fornece a igualdade do valor, uma substituição do é igual a em uma classe derivada deve chamar a implementação herdada do é igual a.
Se você está programando em um idioma que ofereça suporte a sobrecarga de operador e escolha para sobrecarregar o operador de igualdade (= =) para um tipo especificado, o que o tipo deve substituir o é igual a método. Tais implementações do é igual a método deve retornar os mesmos resultados que o operador de igualdade. Essa diretriz a seguir ajudará a garantir que código de biblioteca de classe usando é igual a (como ArrayList e Hashtable) funciona de maneira que seja consistente com a maneira como o operador de igualdade é usado pelo código do aplicativo.
Se você estiver implementando um tipo de valor, você deve considerar a substituição de é igual a método para obter um desempenho maior sobre a implementação padrão do é igual a método em ValueType. Se você substituir é igual a e o idioma oferece suporte a sobrecarga de operador, você deverá sobrecarregar o operador de igualdade para o tipo de valor.
Se você estiver implementando os tipos de referência, você deve considerar a substituição de é igual a método em um tipo de referência, se o seu tipo se parece com um tipo de base, como Point, String, BigNumbere assim por diante. A maioria dos tipos de referência não deverá sobrecarregar o operador de igualdade, mesmo se elas substituirão é igual a. No entanto, se você estiver implementando um tipo de referência destina-se ter a semântica de valor, como, por exemplo, um tipo de número complexo, você deve substituir o operador de igualdade.
Se você implementar a IComparable interface de um determinado tipo, você deve substituir é igual a nesse tipo.
Exemplos
Os exemplos de código a seguir demonstram a implementação, substituindo chamando e sobrecarga de é igual a método.
Implementing the Equals Method
O exemplo de código a seguir contém duas chamadas para a implementação padrão de é igual a método.
Imports System
Class SampleClass
Public Shared Sub Main()
Dim obj1 As New System.Object()
Dim obj2 As New System.Object()
Console.WriteLine(obj1.Equals(obj2))
obj1 = obj2
Console.WriteLine(obj1.Equals(obj2))
End Sub
End Class
using System;
class SampleClass
{
public static void Main()
{
Object obj1 = new Object();
Object obj2 = new Object();
Console.WriteLine(obj1.Equals(obj2));
obj1 = obj2;
Console.WriteLine(obj1.Equals(obj2));
}
}
A saída do código anterior é o seguinte:
False
True
Substituindo o método Equals
O seguinte código exemplo mostra um Point classe substitui o é igual a método para fornecer a igualdade do valor e uma classe Point3D, que é derivada de Point. Porque o Point a substituição da classe do é igual a é o primeiro na cadeia de herança para apresentar a igualdade do valor, o é igual a método da classe base (que é herdada da objeto e verificações de igualdade referencial) não é invocado. No entanto, Point3D.Equals chama Point.Equals porque Point implementa é igual a de maneira que fornece a igualdade do valor.
Namespace Examples.DesignGuidelines.EqualsImplementation
Public Class Point
Protected x As Integer
Protected y As Integer
Public Sub New (xValue As Integer, yValue As Integer)
Me.x = xValue
Me.y = yValue
End Sub
Public Overrides Overloads Function Equals(obj As Object) As Boolean
If obj Is Nothing OrElse Not Me.GetType() Is obj.GetType() Then
Return False
End If
Dim p As Point = CType(obj, Point)
Return Me.x = p.x And Me.y = p.y
End Function
Public Overrides Function GetHashCode() As Integer
Return x Xor y
End Function
End Class
Public Class Point3D
Inherits Point
Private z As Integer
Public Sub New (xValue As Integer, yValue As Integer, zValue As Integer)
MyBase.New(xValue, yValue)
Me.z = zValue
End Sub
Public Overrides Overloads Function Equals(obj As Object) As Boolean
Return MyBase.Equals(obj) And z = CType(obj, Point3D).z
End Function
Public Overrides Function GetHashCode() As Integer
Return MyBase.GetHashCode() Xor z
End Function
End Class
End Namespace
using System;
namespace Examples.DesignGuidelines.EqualsImplementation
{
class Point: object
{
protected int x, y;
public Point(int xValue, int yValue)
{
x = xValue;
y = yValue;
}
public override bool Equals(Object obj)
{
// Check for null values and compare run-time types.
if (obj == null || GetType() != obj.GetType())
return false;
Point p = (Point)obj;
return (x == p.x) && (y == p.y);
}
public override int GetHashCode()
{
return x ^ y;
}
}
class Point3D: Point
{
int z;
public Point3D(int xValue, int yValue, int zValue) : base(xValue, yValue)
{
z = zValue;
}
public override bool Equals(Object obj)
{
return base.Equals(obj) && z == ((Point3D)obj).z;
}
public override int GetHashCode()
{
return base.GetHashCode() ^ z;
}
}
}
using namespace System;
namespace Examples { namespace DesignGuidelines { namespace EqualsImplementation
{
ref class Point : Object
{
protected:
int x, y;
public:
Point(int xValue, int yValue)
{
x = xValue;
y = yValue;
}
virtual bool Equals(Object^ obj) override
{
// Check for null values and compare run-time types.
if (obj == nullptr || GetType() != obj->GetType())
{
return false;
}
Point^ p = (Point^)obj;
return (x == p->x) && (y == p->y);
}
virtual int GetHashCode() override
{
return x ^ y;
}
};
ref class Point3D : Point
{
private:
int z;
public:
Point3D(int xValue, int yValue, int zValue) : Point(xValue, yValue)
{
z = zValue;
}
virtual bool Equals(Object^ obj) override
{
return Point::Equals(obj) && z == ((Point3D^)obj)->z;
}
virtual int GetHashCode() override
{
return Point::GetHashCode() ^ z;
}
};
}}}
O Point.Equals método verifica que o obj argumento não for null, e ele faz referência a uma instância do mesmo tipo de objeto. Se qualquer uma das verificações falhar, o método retorna false. O é igual a método usa o GetType método para determinar se os tipos de tempo de execução dos dois objetos são idênticos. Observe que typeof (TypeOf em Visual Basic) não é usado aqui porque ela retorna o tipo estático. Se o método tivesse usado uma verificação do formulário obj is Point em vez disso, a verificação retornaria true em casos onde obj é uma instância de uma classe derivada de Point, mesmo que obj e a instância atual não são do mesmo tipo de tempo de execução. Tendo verificado que ambos os objetos são do mesmo tipo, os método de projeções obj digitar Point e retorna o resultado de comparar as variáveis de instância de dois objetos.
Em Point3D.Equals, o herdadas é igual a método é chamado antes que qualquer outra coisa seja feita. O herdadas é igual a método verifica se obj não é null, que obj é uma instância da mesma classe de objeto e as variáveis de instância herdadas correspondentes. Somente quando o herdadas é igual a retorna true oferece o método compare as variáveis de instância introduzidas na classe derivada. Especificamente, a projeção para Point3D não é executado, a menos que obj foi determinado ser do tipo Point3D ou uma classe derivada de Point3D.
Usando o método Equals para comparar as variáveis de instância
No exemplo anterior, o operador de igualdade (= =) é usado para comparar as variáveis de instância individual. Em alguns casos, é apropriado usar o é igual a método para comparar as variáveis de instância em um é igual a implementação, conforme mostrado no exemplo de código a seguir.
Imports System
Class Rectangle
Private a, b As Point
Public Overrides Overloads Function Equals(obj As [Object]) As Boolean
If obj Is Nothing Or Not Me.GetType() Is obj.GetType() Then
Return False
End If
Dim r As Rectangle = CType(obj, Rectangle)
' Use Equals to compare instance variables.
Return Me.a.Equals(r.a) And Me.b.Equals(r.b)
End Function
Public Overrides Function GetHashCode() As Integer
Return a.GetHashCode() ^ b.GetHashCode()
End Function
End Class
using System;
class Rectangle
{
Point a, b;
public override bool Equals(Object obj)
{
if (obj == null || GetType() != obj.GetType()) return false;
Rectangle r = (Rectangle)obj;
// Use Equals to compare instance variables.
return a.Equals(r.a) && b.Equals(r.b);
}
public override int GetHashCode()
{
return a.GetHashCode() ^ b.GetHashCode();
}
}
Sobrecarga de operador de igualdade (= =) e o método Equals
Em algumas linguagens de programação, como, por exemplo, C#, sobrecarga de operador é suportado. Quando um tipo sobrecarrega o operador de igualdade (= =), também deverá substituir o é igual a método para fornecer a mesma funcionalidade. Normalmente, isso é feito escrevendo o é igual a método em termos do operador sobrecarregado de igualdade (= =), como no exemplo de código a seguir.
public struct Complex
{
double re, im;
public override bool Equals(Object obj)
{
return obj is Complex && this == (Complex)obj;
}
public override int GetHashCode()
{
return re.GetHashCode() ^ im.GetHashCode();
}
public static bool operator ==(Complex x, Complex y)
{
return x.re == y.re && x.im == y.im;
}
public static bool operator !=(Complex x, Complex y)
{
return !(x == y);
}
}
Porque Complex é C# struct (um tipo de valor), ele é conhecido que nenhuma classe será derivado Complex. Portanto, o é igual a método não precisa comparar o GetType resultados para cada objeto. Em vez disso, ele usa o é operador para verificar o tipo da obj parâmetro.
Portions Copyright 2005 Microsoft Corporation. Todos os direitos reservados.
Portions Copyright Addison-Wesley Corporation. Todos os direitos reservados.
Para obter mais informações sobre as diretrizes de design, consulte a "diretrizes de Design do Framework: Convenções, idiomas e padrões de reutilizável.Bibliotecas de rede" catálogo por Krzysztof Cwalina e Brad Abrams, publicado pela Addison-Wesley, 2005.
Consulte também
Outros recursos
Diretrizes de Design para desenvolvimento bibliotecas de classe