Implementar o método equals

Para obter informações relacionadas sobre como implementar o operador de igualdade (==), consulte Diretrizes para implementação igual e o operador de igualdade (==).

  • Substituir o GetHashCode método para permitir que um tipo para funcionar corretamente em uma tabela de hash.

  • Não lançar uma exceção na implementação de um É igual a método. Em vez disso, retornam False um argumento nulo.

  • Execute o contrato definido na Método objeto.Equals sistema autônomo segue:

    • x.Equals(x) Retorna True.

    • x.Equals(y) Retorna o mesmo valor que y.Equals(x).

    • (x.Equals(y) && y.Equals(z)) Retorna True se e somente se x.Equals(z) Retorna True.

    • Chamadas sucessivas de x.Equals(y) retornar o valor mesmo enquanto sistema autônomo objetos referenciados pelo x e y não são modificados.

    • x.Equals(null) Retorna false.

  • Para alguns tipos de objetos, é desejável que É igual a teste igualdade do valor em vez de igualdade referencial. Essas implementações de É igual a return True se os dois objetos têm o mesmo valor, mesmo que não estejam na mesma instância. A definição do que constitui o valor de um objeto é para 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 do Seqüência de caracteres classe retorna True qualquer duas instâncias de uma seqüência de caracteres que contêm exatamente os mesmos caracteres na mesma ordem.

  • Quando o É igual a método da classe base fornece a igualdade do valor, uma substituir de É igual a em uma classe derivada deve chamar a implementação herdada de É igual a.

  • Se você está programando em um linguagem com suporte para o sobrecarga de operador e escolher sobrecarregar o operador de igualdade (==) para um tipo especificado, esse tipo deve substituir o É igual a método. Essas implementações do É igual a método deve retornar sistema autônomo mesmos resultados que o operador de igualdade. Essa diretriz a seguir irá ajudá-lo a verificar esse código de biblioteca de classes usando o É igual a (por exemplo, ArrayList e Hashtable) funciona na forma que seja consistente com a maneira sistema autônomo o operador de igualdade é usado pelo código do aplicativo.

  • Se você estiver implementando um tipo de valor, você deve considerar substituindo o É igual a método para obter um desempenho maior sobre a implementação padrão do É igual a método ValueType. Se você substituir É igual a e o sobrecarga de operador oferece suporte ao linguagem, você deve sobrecarregar o operador de igualdade para seu tipo de valor.

  • Se você estiver implementando sistema autônomo tipos de referência, você deve considerar substituindo o É igual a método em um tipo de referência, caso seja seu tipo sistema autônomo um tipo de base, sistema autônomo Point, String, BigNumber, e 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 a tiver semântica de valor, sistema autônomo um tipo de número complexo, você deve substituir o operador de igualdade.

  • Se você implementar o IComparable interface de um determinado tipo, você deve substituir É igual a nesse tipo.

Exemplos

Os exemplos de código a seguir demonstram implementar, substituindo chamando e sobrecarregando o É igual a método.

Implementar o método equals

O exemplo de código a seguir contém duas chamadas para a implementação padrão do É 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 exemplo de código a seguir mostra um Point classe substitui o É igual a método para fornecer valor igualdade e uma classe Point3D, que é derivado de Point. Porque o Point substituir da classe do É igual a é o primeiro da cadeia de herança para apresentar a igualdade do valor, a É igual a método da classe base (que é herdada de Objeto e verificações de igualdade referencial) não é invocado. No entanto, Point3D.Equals invoca Point.Equals porque Point implementa É igual a de forma 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;
   }
}
}

The Point.Equals método verifica que o obj argumento não é nulo e que ele faz referência a uma instância do tipo mesmo sistema autônomo esse objeto. Se qualquer uma das verificações falharem, o método retorna False. The É igual a método usa o GetType Método para determinar se o em time de execução tipos dos dois objetos são idênticos. Observe que TypeOf (TypeOf no 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 corrente não são do mesmo tipo de time de execução. Tendo verificado se os dois objetos são do mesmo tipo, o método converte obj to type Point e retorna o resultado de comparar as variáveis de instância dos dois objetos.

In Point3D.Equals, o herdadas É igual a método é chamado antes que qualquer outra coisa seja feita. O herdadasÉ igual a método verifica que obj is not null, que obj é uma instância da mesma classe sistema autônomo este objeto e que coincidem com sistema autônomo variáveis de instância herdada. Somente quando o herdadasÉ igual a returns True faz comparar de método as variáveis de instância introduzidas na classe derivada. Especificamente, a projeção para Point3D não é executado, a menos que obj tiver sido determinado como sendo 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 (==) serve para comparar as variáveis de instância individual. Em alguns casos, é apropriado usar o É igual a método para comparar sistema autônomo variáveis de ocorrência em um É igual a implementação, sistema autônomo neste 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, such sistema autônomo translation from VPE for Csharp, há suporte para o sobrecarga de operador. Quando um tipo sobrecarrega o operador de igualdade (==), ele também deve substituir o É igual a método para fornecer a mesma funcionalidade. Normalmente, isso é realizado ao escrever o É igual a método em termos do operador de igualdade sobrecarregados (==), sistema autônomo 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 é um translation from VPE for Csharp struct (um tipo de valor), ele é conhecido que nenhuma classe será derivada da Complex. Portanto, a É igual a não é necessário comparar o métodoGetType resultados para cada objeto. Em vez disso, ele usa o é operador para verificar o tipo do obj parâmetro.

Partes direitos autorais 2005 Microsoft Corporation. Todos os direitos reservados.

Partes direitos autorais Addison-Wesley Corporation. Todos os direitos reservados.

Para obter mais informações sobre diretrizes de design, consulte a "diretrizes de design do estrutura: Catálogo de convenções, idiomas e padrões para bibliotecas do .NET reutilizável"Krzysztof Cwalina e Brad Abrams, publicado pela Addison-Wesley, 2005.

Consulte também

Outros recursos

Diretrizes de Design para desenvolvimento bibliotecas de classe