Object.Equals Metodo

Definizione

Determina se due istanze di un oggetto sono uguali.

Overload

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

Equals(Object, Object)

Determina se le istanze dell'oggetto specificate sono considerate uguali.

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

public:
 virtual bool Equals(System::Object ^ obj);
public virtual bool Equals (object obj);
public virtual bool Equals (object? obj);
abstract member Equals : obj -> bool
override this.Equals : obj -> bool
Public Overridable Function Equals (obj As Object) As Boolean

Parametri

obj
Object

Oggetto da confrontare con l'oggetto corrente.

Restituisce

Boolean

true se l'oggetto specificato è uguale all'oggetto corrente; in caso contrario, false.

Esempio

Nell'esempio seguente viene illustrata una classe che esegue l'override del metodo per fornire l'uguaglianza dei valori e una classe Point Equals derivata da Point3D Point . Poiché Point esegue l'override Object.Equals(Object) per verificare l'uguaglianza dei valori, Object.Equals(Object) il metodo non viene chiamato. Tuttavia, Point3D.Equals chiama perché implementa in modo che Point.Equals Point Object.Equals(Object) garantisca l'uguaglianza dei valori.

using System;

class Point
{
   protected int x, y;

   public Point() : this(0, 0)
   { }

   public Point(int x, int y)
   {
      this.x = x;
      this.y = y;
   }

   public override bool Equals(Object obj)
   {
      //Check for null and compare run-time types.
      if ((obj == null) || ! this.GetType().Equals(obj.GetType()))
      {
         return false;
      }
      else {
         Point p = (Point) obj;
         return (x == p.x) && (y == p.y);
      }
   }

   public override int GetHashCode()
   {
      return (x << 2) ^ y;
   }

    public override string ToString()
    {
        return String.Format("Point({0}, {1})", x, y);
    }
}

sealed class Point3D: Point
{
   int z;

   public Point3D(int x, int y, int z) : base(x, y)
   {
      this.z = z;
   }

   public override bool Equals(Object obj)
   {
      Point3D pt3 = obj as Point3D;
      if (pt3 == null)
         return false;
      else
         return base.Equals((Point)obj) && z == pt3.z;
   }

   public override int GetHashCode()
   {
      return (base.GetHashCode() << 2) ^ z;
   }

   public override String ToString()
   {
        return String.Format("Point({0}, {1}, {2})", x, y, z);
    }
}

class Example
{
  public static void Main()
  {
     Point point2D = new Point(5, 5);
     Point3D point3Da = new Point3D(5, 5, 2);
     Point3D point3Db = new Point3D(5, 5, 2);
     Point3D point3Dc = new Point3D(5, 5, -1);

     Console.WriteLine("{0} = {1}: {2}",
                       point2D, point3Da, point2D.Equals(point3Da));
     Console.WriteLine("{0} = {1}: {2}",
                       point2D, point3Db, point2D.Equals(point3Db));
     Console.WriteLine("{0} = {1}: {2}",
                       point3Da, point3Db, point3Da.Equals(point3Db));
     Console.WriteLine("{0} = {1}: {2}",
                       point3Da, point3Dc, point3Da.Equals(point3Dc));
  }
}
// The example displays the following output:
//       Point(5, 5) = Point(5, 5, 2): False
//       Point(5, 5) = Point(5, 5, 2): False
//       Point(5, 5, 2) = Point(5, 5, 2): True
//       Point(5, 5, 2) = Point(5, 5, -1): False
Class Point
    Protected x, y As Integer
    
    Public Sub New() 
        Me.x = 0
        Me.y = 0
    End Sub
    
    Public Sub New(x As Integer, y As Integer) 
        Me.x = x
        Me.y = y
    End Sub 

    Public Overrides Function Equals(obj As Object) As Boolean 
        ' Check for null and compare run-time types.
        If obj Is Nothing OrElse Not Me.GetType().Equals(obj.GetType()) Then
           Return False
        Else
           Dim p As Point = DirectCast(obj, Point)
           Return x = p.x AndAlso y = p.y
        End If
    End Function 

    Public Overrides Function GetHashCode() As Integer 
        Return (x << 2) XOr y
    End Function

    Public Overrides Function ToString() As String
        Return String.Format("Point({0}, {1})", x, y)
    End Function
End Class

Class Point3D : Inherits Point
    Private z As Integer
    
    Public Sub New(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) 
        MyBase.New(x, y) 
        Me.z = Z
    End Sub

    Public Overrides Function Equals(ByVal obj As Object) As Boolean 
        Dim pt3 As Point3D = TryCast(obj, Point3D)
        If pt3 Is Nothing Then
           Return False
        Else
           Return MyBase.Equals(CType(pt3, Point)) AndAlso z = pt3.Z  
        End If
    End Function
    
    Public Overrides Function GetHashCode() As Integer 
        Return (MyBase.GetHashCode() << 2) XOr z
    End Function 
    
    Public Overrides Function ToString() As String
        Return String.Format("Point({0}, {1}, {2})", x, y, z)
    End Function
End Class 

Module Example
    Public Sub Main() 
        Dim point2D As New Point(5, 5)
        Dim point3Da As New Point3D(5, 5, 2)
        Dim point3Db As New Point3D(5, 5, 2)
        Dim point3Dc As New Point3D(5, 5, -1)
        
        Console.WriteLine("{0} = {1}: {2}", 
                          point2D, point3Da, point2D.Equals(point3Da))
        Console.WriteLine("{0} = {1}: {2}", 
                          point2D, point3Db, point2D.Equals(point3Db))        
        Console.WriteLine("{0} = {1}: {2}", 
                          point3Da, point3Db, point3Da.Equals(point3Db))
        Console.WriteLine("{0} = {1}: {2}", 
                          point3Da, point3Dc, point3Da.Equals(point3Dc))
    End Sub  
End Module 
' The example displays the following output
'       Point(5, 5) = Point(5, 5, 2): False
'       Point(5, 5) = Point(5, 5, 2): False
'       Point(5, 5, 2) = Point(5, 5, 2): True
'       Point(5, 5, 2) = Point(5, 5, -1): False

Il metodo verifica che l'argomento non sia Null e che faccia riferimento a un'istanza dello Point.Equals stesso tipo di questo obj oggetto. Se uno dei due controlli ha esito negativo, il metodo restituisce false .

Il Point.Equals metodo chiama il metodo per GetType determinare se i tipi di run-time dei due oggetti sono identici. Se il metodo ha usato un controllo del formato in C# o in Visual Basic, il controllo restituirebbe nei casi in cui è un'istanza di una classe derivata di , anche se e l'istanza corrente non sono dello stesso tipo di obj is Point TryCast(obj, Point) true obj Point obj run-time. Dopo aver verificato che entrambi gli oggetti sono dello stesso tipo, il metodo esegue il cast al tipo e restituisce il risultato del confronto dei campi di obj Point istanza dei due oggetti.

In Point3D.Equals il metodo Point.Equals ereditato, che esegue l'override di , viene Object.Equals(Object) richiamato prima di qualsiasi altra operazione. Poiché è una classe sealed ( in Visual Basic), un controllo nel Point3D NotInheritable formato in C# o in Visual Basic è adeguato per garantire che sia obj is Point TryCast(obj, Point) un oggetto obj Point3D . Se è un oggetto , viene eseguito il cast a un oggetto e Point3D Point viene passato all'implementazione della classe di base di Equals . Solo quando il metodo Point.Equals ereditato restituisce , true il metodo confronta i campi di istanza introdotti nella classe z derivata.

Nell'esempio seguente viene definita Rectangle una classe che implementa internamente un rettangolo come due oggetti Point . La Rectangle classe esegue anche l'override di per fornire Object.Equals(Object) l'uguaglianza dei valori.

using System;

class Rectangle
{
   private Point a, b;

   public Rectangle(int upLeftX, int upLeftY, int downRightX, int downRightY)
   {
      this.a = new Point(upLeftX, upLeftY);
      this.b = new Point(downRightX, downRightY);
   }

   public override bool Equals(Object obj)
   {
      // Perform an equality check on two rectangles (Point object pairs).
      if (obj == null || GetType() != obj.GetType())
          return false;
      Rectangle r = (Rectangle)obj;
      return a.Equals(r.a) && b.Equals(r.b);
   }

   public override int GetHashCode()
   {
      return Tuple.Create(a, b).GetHashCode();
   }

    public override String ToString()
    {
       return String.Format("Rectangle({0}, {1}, {2}, {3})",
                            a.x, a.y, b.x, b.y);
    }
}

class Point
{
  internal int x;
  internal int y;

  public Point(int X, int Y)
  {
     this.x = X;
     this.y = Y;
  }

  public override bool Equals (Object obj)
  {
     // Performs an equality check on two points (integer pairs).
     if (obj == null || GetType() != obj.GetType()) return false;
     Point p = (Point)obj;
     return (x == p.x) && (y == p.y);
  }

  public override int GetHashCode()
  {
     return Tuple.Create(x, y).GetHashCode();
  }
}

class Example
{
   public static void Main()
   {
      Rectangle r1 = new Rectangle(0, 0, 100, 200);
      Rectangle r2 = new Rectangle(0, 0, 100, 200);
      Rectangle r3 = new Rectangle(0, 0, 150, 200);

      Console.WriteLine("{0} = {1}: {2}", r1, r2, r1.Equals(r2));
      Console.WriteLine("{0} = {1}: {2}", r1, r3, r1.Equals(r3));
      Console.WriteLine("{0} = {1}: {2}", r2, r3, r2.Equals(r3));
   }
}
// The example displays the following output:
//    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 100, 200): True
//    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False
//    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False
Class Rectangle 
    Private a, b As Point
    
    Public Sub New(ByVal upLeftX As Integer, ByVal upLeftY As Integer, _
                   ByVal downRightX As Integer, ByVal downRightY As Integer) 
        Me.a = New Point(upLeftX, upLeftY)
        Me.b = New Point(downRightX, downRightY)
    End Sub 
    
    Public Overrides Function Equals(ByVal obj As [Object]) As Boolean 
        ' Performs an equality check on two rectangles (Point object pairs).
        If obj Is Nothing OrElse Not [GetType]().Equals(obj.GetType()) Then
            Return False
        End If
        Dim r As Rectangle = CType(obj, Rectangle)
        Return a.Equals(r.a) AndAlso b.Equals(r.b)
    End Function

    Public Overrides Function GetHashCode() As Integer 
        Return Tuple.Create(a, b).GetHashCode()
    End Function 

    Public Overrides Function ToString() As String
       Return String.Format("Rectangle({0}, {1}, {2}, {3})",
                            a.x, a.y, b.x, b.y) 
    End Function
End Class 

Class Point
    Friend x As Integer
    Friend y As Integer
    
    Public Sub New(ByVal X As Integer, ByVal Y As Integer) 
        Me.x = X
        Me.y = Y
    End Sub 

    Public Overrides Function Equals(ByVal obj As [Object]) As Boolean 
        ' Performs an equality check on two points (integer pairs).
        If obj Is Nothing OrElse Not [GetType]().Equals(obj.GetType()) Then
            Return False
        Else
           Dim p As Point = CType(obj, Point)
           Return x = p.x AndAlso y = p.y
        End If
    End Function 
    
    Public Overrides Function GetHashCode() As Integer 
        Return Tuple.Create(x, y).GetHashCode()
    End Function 
End Class  

Class Example
    Public Shared Sub Main() 
        Dim r1 As New Rectangle(0, 0, 100, 200)
        Dim r2 As New Rectangle(0, 0, 100, 200)
        Dim r3 As New Rectangle(0, 0, 150, 200)
        
        Console.WriteLine("{0} = {1}: {2}", r1, r2, r1.Equals(r2))
        Console.WriteLine("{0} = {1}: {2}", r1, r3, r1.Equals(r3))
        Console.WriteLine("{0} = {1}: {2}", r2, r3, r2.Equals(r3))
    End Sub 
End Class 
' The example displays the following output:
'    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 100, 200): True
'    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False
'    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False

Alcuni linguaggi, ad esempio C# e Visual Basic l'overload degli operatori. Quando un tipo esegue l'overload dell'operatore di uguaglianza, deve eseguire anche l'override del Equals(Object) metodo per fornire la stessa funzionalità. Questa operazione viene in genere eseguita scrivendo il metodo in termini di operatore di uguaglianza di Equals(Object) overload, come nell'esempio seguente.

using System;

public struct Complex
{
   public double re, im;

   public override bool Equals(Object obj)
   {
      return obj is Complex && this == (Complex)obj;
   }

   public override int GetHashCode()
   {
      return Tuple.Create(re, 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);
   }

    public override String ToString()
    {
       return String.Format("({0}, {1})", re, im);
    }
}

class MyClass
{
  public static void Main()
  {
    Complex cmplx1, cmplx2;

    cmplx1.re = 4.0;
    cmplx1.im = 1.0;

    cmplx2.re = 2.0;
    cmplx2.im = 1.0;

    Console.WriteLine("{0} <> {1}: {2}", cmplx1, cmplx2, cmplx1 != cmplx2);
    Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2));

    cmplx2.re = 4.0;

    Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1 == cmplx2);
    Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2));
  }
}
// The example displays the following output:
//       (4, 1) <> (2, 1): True
//       (4, 1) = (2, 1): False
//       (4, 1) = (4, 1): True
//       (4, 1) = (4, 1): True
Public Structure Complex
    Public re, im As Double
    
    Public Overrides Function Equals(ByVal obj As [Object]) As Boolean 
        Return TypeOf obj Is Complex AndAlso Me = CType(obj, Complex)
    End Function 
    
    Public Overrides Function GetHashCode() As Integer 
        Return Tuple.Create(re, im).GetHashCode()
    End Function 
    
    Public Shared Operator = (x As Complex, y As Complex) As Boolean
       Return x.re = y.re AndAlso x.im = y.im
    End Operator 
    
    Public Shared Operator <> (x As Complex, y As Complex) As Boolean
       Return Not (x = y)
    End Operator 
    
    Public Overrides Function ToString() As String
       Return String.Format("({0}, {1})", re, im)
    End Function 
End Structure

Class Example
   Public Shared Sub Main() 
      Dim cmplx1, cmplx2 As Complex
        
      cmplx1.re = 4.0
      cmplx1.im = 1.0
        
      cmplx2.re = 2.0
      cmplx2.im = 1.0

      Console.WriteLine("{0} <> {1}: {2}", cmplx1, cmplx2, cmplx1 <> cmplx2)        
      Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2))        
      
      cmplx2.re = 4.0
        
      Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1 = cmplx2)        
      Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2))        
   End Sub
End Class 
' The example displays the following output:
'       (4, 1) <> (2, 1): True
'       (4, 1) = (2, 1): False
'       (4, 1) = (4, 1): True
'       (4, 1) = (4, 1): True

Poiché Complex è un tipo valore, non può essere derivato da . Pertanto, l'override del metodo non deve chiamare per determinare il tipo di run-time preciso di ogni oggetto, ma può usare Equals(Object) l'operatore in C# o l'operatore in Visual Basic per controllare il tipo del GetType is TypeOf obj parametro.

Commenti

Il tipo di confronto tra l'istanza corrente e il parametro dipende dal fatto che l'istanza corrente sia un tipo riferimento obj o un tipo valore.

  • Se l'istanza corrente è un tipo riferimento, il metodo verifica l'uguaglianza dei riferimenti e una chiamata al metodo Equals(Object) equivale a una chiamata al metodo Equals(Object) ReferenceEquals . L'uguaglianza dei riferimenti significa che le variabili oggetto confrontate fanno riferimento allo stesso oggetto. Nell'esempio seguente viene illustrato il risultato di tale confronto. Definisce una classe, che è un tipo riferimento, e chiama il costruttore della classe per creare un'istanza di due nuovi Person Person Person oggetti, person1a e , che hanno lo stesso person2 valore. Assegna anche a person1a un'altra variabile oggetto, person1b . Come illustrato nell'output dell'esempio, person1a e sono uguali perché fanno riferimento allo stesso person1b oggetto. Tuttavia, person1a e non sono person2 uguali, anche se hanno lo stesso valore.

    using System;
    
    // Define a reference type that does not override Equals.
    public class Person
    {
       private string personName;
    
       public Person(string name)
       {
          this.personName = name;
       }
    
       public override string ToString()
       {
          return this.personName;
       }
    }
    
    public class Example
    {
       public static void Main()
       {
          Person person1a = new Person("John");
          Person person1b = person1a;
          Person person2 = new Person(person1a.ToString());
    
          Console.WriteLine("Calling Equals:");
          Console.WriteLine("person1a and person1b: {0}", person1a.Equals(person1b));
          Console.WriteLine("person1a and person2: {0}", person1a.Equals(person2));
    
          Console.WriteLine("\nCasting to an Object and calling Equals:");
          Console.WriteLine("person1a and person1b: {0}", ((object) person1a).Equals((object) person1b));
          Console.WriteLine("person1a and person2: {0}", ((object) person1a).Equals((object) person2));
       }
    }
    // The example displays the following output:
    //       person1a and person1b: True
    //       person1a and person2: False
    //
    //       Casting to an Object and calling Equals:
    //       person1a and person1b: True
    //       person1a and person2: False
    
    ' Define a reference type that does not override Equals.
    Public Class Person
       Private personName As String
       
       Public Sub New(name As String)
          Me.personName = name
       End Sub
       
       Public Overrides Function ToString() As String
          Return Me.personName
       End Function 
    End Class
    
    Module Example
       Public Sub Main()
          Dim person1a As New Person("John")
          Dim person1b As Person = person1a
          Dim person2 As New Person(person1a.ToString())
          
          Console.WriteLine("Calling Equals:") 
          Console.WriteLine("person1a and person1b: {0}", person1a.Equals(person1b))               
          Console.WriteLine("person1a and person2: {0}", person1a.Equals(person2))  
          Console.WriteLine()
          
          Console.WriteLine("Casting to an Object and calling Equals:")
          Console.WriteLine("person1a and person1b: {0}", CObj(person1a).Equals(CObj(person1b)))
          Console.WriteLine("person1a and person2: {0}", CObj(person1a).Equals(CObj(person2))) 
       End Sub
    End Module
    ' The example displays the following output:
    '       Calling Equals:
    '       person1a and person1b: True
    '       person1a and person2: False
    '       
    '       Casting to an Object and calling Equals:
    '       person1a and person1b: True
    '       person1a and person2: False
    
  • Se l'istanza corrente è un tipo valore, il Equals(Object) metodo verifica l'uguaglianza dei valori. L'uguaglianza dei valori significa quanto segue:

    • I due oggetti sono dello stesso tipo. Come illustrato nell'esempio seguente, un oggetto con valore 12 non è uguale a un oggetto con valore 12, perché i due oggetti hanno tipi di Byte Int32 run-time diversi.

      byte value1 = 12;
      int value2 = 12;
      
      object object1 = value1;
      object object2 = value2;
      
      Console.WriteLine("{0} ({1}) = {2} ({3}): {4}",
                        object1, object1.GetType().Name,
                        object2, object2.GetType().Name,
                        object1.Equals(object2));
      
      // The example displays the following output:
      //        12 (Byte) = 12 (Int32): False
      
      Module Example
         Public Sub Main()
            Dim value1 As Byte = 12
            Dim value2 As Integer = 12
            
            Dim object1 As Object = value1
            Dim object2 As Object = value2
            
            Console.WriteLine("{0} ({1}) = {2} ({3}): {4}",
                              object1, object1.GetType().Name,
                              object2, object2.GetType().Name,
                              object1.Equals(object2))
         End Sub
      End Module
      ' The example displays the following output:
      '       12 (Byte) = 12 (Int32): False
      
    • I valori dei campi pubblico e privato dei due oggetti sono uguali. Nell'esempio seguente viene verificata l'uguaglianza dei valori. Definisce una struttura , che è un tipo valore, e chiama il costruttore della classe per creare un'istanza di due nuovi Person Person Person oggetti, person1 e , che hanno lo stesso person2 valore. Come illustrato nell'output dell'esempio, anche se le due variabili oggetto fanno riferimento a oggetti diversi e sono uguali perché hanno lo stesso person1 valore per il campo person2 personName privato.

      using System;
      
      // Define a value type that does not override Equals.
      public struct Person
      {
         private string personName;
      
         public Person(string name)
         {
            this.personName = name;
         }
      
         public override string ToString()
         {
            return this.personName;
         }
      }
      
      public struct Example
      {
         public static void Main()
         {
            Person person1 = new Person("John");
            Person person2 = new Person("John");
      
            Console.WriteLine("Calling Equals:");
            Console.WriteLine(person1.Equals(person2));
      
            Console.WriteLine("\nCasting to an Object and calling Equals:");
            Console.WriteLine(((object) person1).Equals((object) person2));
         }
      }
      // The example displays the following output:
      //       Calling Equals:
      //       True
      //
      //       Casting to an Object and calling Equals:
      //       True
      
      ' Define a value type that does not override Equals.
      Public Structure Person
         Private personName As String
         
         Public Sub New(name As String)
            Me.personName = name
         End Sub
         
         Public Overrides Function ToString() As String
            Return Me.personName
         End Function 
      End Structure
      
      Module Example
         Public Sub Main()
            Dim p1 As New Person("John")
            Dim p2 As New Person("John")
            
            Console.WriteLine("Calling Equals:") 
            Console.WriteLine(p1.Equals(p2))
            Console.WriteLine()
            
            Console.WriteLine("Casting to an Object and calling Equals:")
            Console.WriteLine(CObj(p1).Equals(p2))
         End Sub
      End Module
      ' The example displays the following output:
      '       Calling Equals:
      '       True
      '       
      '       Casting to an Object and calling Equals:
      '       True
      

Poiché la classe è la classe di base per tutti i tipi nel .NET Framework, il metodo fornisce il confronto di uguaglianza predefinito Object per tutti gli altri Object.Equals(Object) tipi. Tuttavia, i tipi spesso eseguono l'override Equals del metodo per implementare l'uguaglianza dei valori. Per altre informazioni, vedere le sezioni Notes for Callers (Note per i chiamanti) e Notes for Inheritors (Note per i chiamanti) e Notes for Inheritors (Note per gli eredi).

Note per il runtime Windows

Quando si chiama l'overload del metodo su una classe in Windows Runtime, fornisce il comportamento predefinito per le classi che non eseguono Equals(Object) l'override di Equals(Object) . Fa parte del supporto fornito dal .NET Framework per Windows Runtime (vedere Supporto di .NET Framework per le app di Windows Store e Windows Runtime). Le classi nel Windows runtime non ereditano Object e attualmente non implementano un metodo Equals(Object) . Tuttavia, sembrano avere i metodi , e quando vengono utilizzati nel codice C# o Visual Basic e il .NET Framework fornisce il comportamento predefinito per ToString Equals(Object) questi GetHashCode metodi.

Nota

Windows Le classi di runtime scritte in C# o Visual Basic possibile eseguire l'override Equals(Object) dell'overload del metodo .

Note per i chiamanti

Le classi derivate spesso eseguono Object.Equals(Object) l'override del metodo per implementare l'uguaglianza dei valori. Inoltre, i tipi forniscono spesso anche un overload fortemente tipizzato aggiuntivo al metodo , in genere Equals implementando IEquatable<T> l'interfaccia . Quando si chiama il metodo per verificare l'uguaglianza, è necessario sapere se l'istanza corrente esegue l'override e come viene risolta una particolare Equals Object.Equals chiamata a un Equals metodo. In caso contrario, è possibile che si esegua un test di uguaglianza diverso da quello previsto e che il metodo restituirà un valore imprevisto.

Nell'esempio seguente viene illustrato questo concetto. Crea un'istanza StringBuilder di tre oggetti con stringhe identiche e quindi effettua quattro chiamate ai metodi Equals . La prima chiamata al metodo restituisce true e le tre rimanenti restituiscono false .

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      StringBuilder sb1 = new StringBuilder("building a string...");
      StringBuilder sb2 = new StringBuilder("building a string...");

      Console.WriteLine("sb1.Equals(sb2): {0}", sb1.Equals(sb2));
      Console.WriteLine("((Object) sb1).Equals(sb2): {0}",
                        ((Object) sb1).Equals(sb2));
      Console.WriteLine("Object.Equals(sb1, sb2): {0}",
                        Object.Equals(sb1, sb2));

      Object sb3 = new StringBuilder("building a string...");
      Console.WriteLine("\nsb3.Equals(sb2): {0}", sb3.Equals(sb2));
   }
}
// The example displays the following output:
//       sb1.Equals(sb2): True
//       ((Object) sb1).Equals(sb2): False
//       Object.Equals(sb1, sb2): False
//
//       sb3.Equals(sb2): False
Imports System.Text

Module Example
   Public Sub Main()
      Dim sb1 As New StringBuilder("building a string...")
      Dim sb2 As New StringBuilder("building a string...")
      
      Console.WriteLine("sb1.Equals(sb2): {0}", sb1.Equals(sb2))
      Console.WriteLine("CObj(sb1).Equals(sb2): {0}", 
                        CObj(sb1).Equals(sb2))
      Console.WriteLine("Object.Equals(sb1, sb2): {0}",
                        Object.Equals(sb1, sb2))                  
      
      Console.WriteLine()
      Dim sb3 As Object = New StringBuilder("building a string...")
      Console.WriteLine("sb3.Equals(sb2): {0}", sb3.Equals(sb2))                              
   End Sub
End Module
' The example displays the following output:
'       sb1.Equals(sb2): True
'       CObj(sb1).Equals(sb2): False
'       Object.Equals(sb1, sb2): False
'
'       sb3.Equals(sb2): False

Nel primo caso viene chiamato l'overload del metodo fortemente tipizzato, che verifica StringBuilder.Equals(StringBuilder) l'uguaglianza dei valori. Poiché le stringhe assegnate ai due StringBuilder oggetti sono uguali, il metodo restituisce true . Tuttavia, StringBuilder non esegue l'override di Object.Equals(Object) . Per questo problema, quando viene eseguito il cast dell'oggetto a un oggetto , quando un'istanza viene assegnata a una variabile di tipo e quando al metodo vengono passati due oggetti , viene chiamato il metodo StringBuilder Object StringBuilder Object Object.Equals(Object, Object) StringBuilder Object.Equals(Object) predefinito. Poiché StringBuilder è un tipo riferimento, equivale a passare i due oggetti al metodo StringBuilder ReferenceEquals . Anche se tutti StringBuilder e tre gli oggetti contengono stringhe identiche, fanno riferimento a tre oggetti distinti. Di conseguenza, queste tre chiamate al metodo restituiscono false .

È possibile confrontare l'oggetto corrente con un altro oggetto per verificarne l'uguaglianza dei riferimenti chiamando il ReferenceEquals metodo . In Visual Basic è anche possibile usare la parola is chiave , ad esempio If Me Is otherObject Then ... .

Note per gli eredi

Quando si definisce un tipo personalizzato, tale tipo eredita la funzionalità definita dal Equals metodo del relativo tipo di base. Nella tabella seguente viene elencata l'implementazione predefinita del metodo per le principali categorie di tipi Equals nella .NET Framework.

Categoria di tipi Uguaglianza definita da Commenti
Classe derivata direttamente da Object Object.Equals(Object) Uguaglianza dei riferimenti; equivale a chiamare Object.ReferenceEquals .
Struttura ValueType.Equals Uguaglianza di valori; confronto diretto byte per byte o confronto campo per campo tramite reflection.
Enumerazione Enum.Equals I valori devono avere lo stesso tipo di enumerazione e lo stesso valore sottostante.
Delegato MulticastDelegate.Equals I delegati devono avere lo stesso tipo con elenchi di chiamate identici.
Interfaccia Object.Equals(Object) Uguaglianza dei riferimenti.

Per un tipo di valore, è sempre consigliabile eseguire l'override di , perché i test di uguaglianza basati Equals sulla reflection offrono prestazioni scarse. È anche possibile eseguire l'override dell'implementazione predefinita di per i tipi riferimento per verificare l'uguaglianza di valori anziché l'uguaglianza dei riferimenti e per definire il significato preciso Equals dell'uguaglianza di valori. Tali implementazioni di Equals true restituiscono se i due oggetti hanno lo stesso valore, anche se non si tratta della stessa istanza. L'implementatore del tipo decide cosa costituisce il valore di un oggetto, ma in genere sono alcuni o tutti i dati archiviati nelle variabili di istanza dell'oggetto. Ad esempio, il valore di un oggetto è basato sui caratteri della stringa. Il metodo esegue l'override del metodo da restituire per due istanze di stringa qualsiasi che contengono gli stessi caratteri nello String String.Equals(Object) stesso Object.Equals(Object) true ordine.

Nell'esempio seguente viene illustrato come eseguire l'override Object.Equals(Object) del metodo per verificare l'uguaglianza dei valori. Esegue l'override Equals del metodo per la classe Person . Se accettasse l'implementazione di uguaglianza della classe di base, due oggetti sarebbero uguali solo se fanno Person riferimento a un singolo Person oggetto. In questo caso, tuttavia, due Person oggetti sono uguali se hanno lo stesso valore per la proprietà Person.Id .

public class Person
{
   private string idNumber;
   private string personName;

   public Person(string name, string id)
   {
      this.personName = name;
      this.idNumber = id;
   }

   public override bool Equals(Object obj)
   {
      Person personObj = obj as Person;
      if (personObj == null)
         return false;
      else
         return idNumber.Equals(personObj.idNumber);
   }

   public override int GetHashCode()
   {
      return this.idNumber.GetHashCode();
   }
}

public class Example
{
   public static void Main()
   {
      Person p1 = new Person("John", "63412895");
      Person p2 = new Person("Jack", "63412895");
      Console.WriteLine(p1.Equals(p2));
      Console.WriteLine(Object.Equals(p1, p2));
   }
}
// The example displays the following output:
//       True
//       True
Public Class Person
   Private idNumber As String
   Private personName As String
   
   Public Sub New(name As String, id As String)
      Me.personName = name
      Me.idNumber = id
   End Sub
   
   Public Overrides Function Equals(obj As Object) As Boolean
      Dim personObj As Person = TryCast(obj, Person) 
      If personObj Is Nothing Then
         Return False
      Else
         Return idNumber.Equals(personObj.idNumber)
      End If   
   End Function
   
   Public Overrides Function GetHashCode() As Integer
      Return Me.idNumber.GetHashCode() 
   End Function
End Class

Module Example
   Public Sub Main()
      Dim p1 As New Person("John", "63412895")
      Dim p2 As New Person("Jack", "63412895")
      Console.WriteLine(p1.Equals(p2))
      Console.WriteLine(Object.Equals(p1, p2))
   End Sub
End Module
' The example displays the following output:
'       True
'       True

Oltre a eseguire l'override Equals di , è possibile implementare l'interfaccia per fornire un test fortemente IEquatable<T> tipizzato per l'uguaglianza.

Le istruzioni seguenti devono essere true per tutte le implementazioni del Equals(Object) metodo . Nell'elenco x , y , e rappresentano riferimenti a oggetti che non sono z Null.

  • x.Equals(x) restituisce true , ad eccezione dei casi in cui sono coinvolti tipi a virgola mobile. Vedere ISO/IEC/IEEE 60559:2011, Information technology -- Microprocessor Systems -- Floating-Point aritmetica.

  • y.Equals(x) restituisce lo stesso valore di x.Equals(y).

  • x.Equals(y) restituisce true se e sono entrambi x y NaN .

  • Se (x.Equals(y) && y.Equals(z)) restituisce , restituisce true x.Equals(z) true .

  • Chiamate successive per restituire lo stesso valore, purché gli oggetti a cui x.Equals(y) fa riferimento e non siano stati x y modificati.

  • x.Equals(null) restituisce false.

Le implementazioni Equals di non devono generare eccezioni. Devono sempre restituire un valore. Ad esempio, se obj è , il metodo deve restituire invece di generare null Equals false un'eccezione ArgumentNullException .

Quando si esegue l'override di Equals(Object) :

  • I tipi che implementano IComparable devono eseguire l'override di Equals(Object) .

  • Anche i tipi che Equals(Object) eseguono l'override devono eseguire l'override. In caso contrario, le GetHashCode tabelle hash potrebbero non funzionare correttamente.

  • È consigliabile implementare IEquatable<T> l'interfaccia per supportare test fortemente tipizzato per l'uguaglianza. IEquatable<T>.EqualsL'implementazione deve restituire risultati coerenti con Equals .

  • Se il linguaggio di programmazione supporta l'overload dell'operatore e si esegue l'overload dell'operatore di uguaglianza per un determinato tipo, è necessario eseguire anche l'override del metodo per restituire lo stesso risultato Equals(Object) dell'operatore di uguaglianza. Ciò consente di garantire che il codice della libreria di classi che usa (ad esempio e ) si comporti in modo coerente con il modo in cui l'operatore di uguaglianza viene usato dal codice Equals ArrayList Hashtable dell'applicazione.

Linee guida per i tipi di riferimento

Le linee guida seguenti si applicano all'override Equals(Object) di per un tipo riferimento:

  • Valutare la possibilità di eseguire l'override se la semantica del tipo è basata sul fatto che il Equals tipo rappresenta alcuni valori.

  • La maggior parte dei tipi riferimento non deve eseguire l'overload dell'operatore di uguaglianza, anche se eseguono l'override di Equals . Tuttavia, se si implementa un tipo riferimento che deve avere una semantica dei valori, ad esempio un tipo di numero complesso, è necessario eseguire l'override dell'operatore di uguaglianza.

  • Non è consigliabile eseguire Equals l'override su un tipo di riferimento modificabile. Ciò è dovuto al Equals fatto che l'override richiede anche l'override del GetHashCode metodo , come illustrato nella sezione precedente. Ciò significa che il codice hash di un'istanza di un tipo riferimento modificabile può cambiare durante la sua durata, causando la perdita dell'oggetto in una tabella hash.

Linee guida per i tipi valore

Le linee guida seguenti si applicano all'override Equals(Object) di per un tipo di valore:

  • Se si definisce un tipo valore che include uno o più campi i cui valori sono tipi riferimento, è necessario eseguire l'override di Equals(Object) . L'implementazione fornita da esegue un confronto byte per byte per i tipi valore i cui campi sono tutti tipi valore, ma usa la reflection per eseguire un confronto campo per campo dei tipi valore i cui campi includono tipi Equals(Object) ValueType riferimento.

  • Se si esegue l'override Equals e il linguaggio di sviluppo supporta l'overload degli operatori, è necessario eseguire l'overload dell'operatore di uguaglianza.

  • È necessario implementare IEquatable<T> l'interfaccia . La chiamata al metodo fortemente IEquatable<T>.Equals tipizzato evita la boxing dell'argomento. obj

Vedi anche

Si applica a

Equals(Object, Object)

Determina se le istanze dell'oggetto specificate sono considerate uguali.

public:
 static bool Equals(System::Object ^ objA, System::Object ^ objB);
public static bool Equals (object objA, object objB);
public static bool Equals (object? objA, object? objB);
static member Equals : obj * obj -> bool
Public Shared Function Equals (objA As Object, objB As Object) As Boolean

Parametri

objA
Object

Primo oggetto da confrontare.

objB
Object

Secondo oggetto da confrontare.

Restituisce

Boolean

true se gli oggetti sono considerati uguali; in caso contrario, false. Se entrambi i parametri objA e objB sono null, il metodo restituisce true.

Esempio

L'esempio seguente illustra Equals(Object, Object) il metodo e lo confronta con il metodo ReferenceEquals .

using System;

public class Example
{
   public static void Main()
   {
      Dog m1 = new Dog("Alaskan Malamute");
      Dog m2 = new Dog("Alaskan Malamute");
      Dog g1 = new Dog("Great Pyrenees");
      Dog g2 = g1;
      Dog d1 = new Dog("Dalmation");
      Dog n1 = null;
      Dog n2 = null;

      Console.WriteLine("null = null: {0}", Object.Equals(n1, n2));
      Console.WriteLine("null Reference Equals null: {0}\n", Object.ReferenceEquals(n1, n2));

      Console.WriteLine("{0} = {1}: {2}", g1, g2, Object.Equals(g1, g2));
      Console.WriteLine("{0} Reference Equals {1}: {2}\n", g1, g2, Object.ReferenceEquals(g1, g2));

      Console.WriteLine("{0} = {1}: {2}", m1, m2, Object.Equals(m1, m2));
      Console.WriteLine("{0} Reference Equals {1}: {2}\n", m1, m2, Object.ReferenceEquals(m1, m2));

      Console.WriteLine("{0} = {1}: {2}", m1, d1, Object.Equals(m1, d1));
      Console.WriteLine("{0} Reference Equals {1}: {2}", m1, d1, Object.ReferenceEquals(m1, d1));
   }
}

public class Dog
{
   // Public field.
   public string Breed;

   // Class constructor.
   public Dog(string dogBreed)
   {
      this.Breed = dogBreed;
   }

   public override bool Equals(Object obj)
   {
      if (obj == null || !(obj is Dog))
         return false;
      else
         return this.Breed == ((Dog) obj).Breed;
   }

   public override int GetHashCode()
   {
      return this.Breed.GetHashCode();
   }

   public override string ToString()
   {
      return this.Breed;
   }
}
// The example displays the following output:
//       null = null: True
//       null Reference Equals null: True
//
//       Great Pyrenees = Great Pyrenees: True
//       Great Pyrenees Reference Equals Great Pyrenees: True
//
//       Alaskan Malamute = Alaskan Malamute: True
//       Alaskan Malamute Reference Equals Alaskan Malamute: False
//
//       Alaskan Malamute = Dalmation: False
//       Alaskan Malamute Reference Equals Dalmation: False
Module Example
   Public Sub Main()
      Dim m1 As New Dog("Alaskan Malamute")
      Dim m2 As New Dog("Alaskan Malamute")
      Dim g1 As New Dog("Great Pyrenees")
      Dim g2 As Dog = g1
      Dim d1 As New Dog("Dalmation")
      Dim n1 As Dog = Nothing
      Dim n2 As Dog = Nothing
      
      Console.WriteLine("null = null: {0}", Object.Equals(n1, n2))
      Console.WriteLine("null Reference Equals null: {0}", Object.ReferenceEquals(n1, n2))
      Console.WriteLine()
      
      Console.WriteLine("{0} = {1}: {2}", g1, g2, Object.Equals(g1, g2))
      Console.WriteLine("{0} Reference Equals {1}: {2}", g1, g2, Object.ReferenceEquals(g1, g2))
      Console.WriteLine()
      
      Console.WriteLine("{0} = {1}: {2}", m1, m2, Object.Equals(m1, m2))
      Console.WriteLine("{0} Reference Equals {1}: {2}", m1, m2, Object.ReferenceEquals(m1, m2))
      Console.WriteLine()
      
      Console.WriteLine("{0} = {1}: {2}", m1, d1, Object.Equals(m1, d1))  
      Console.WriteLine("{0} Reference Equals {1}: {2}", m1, d1, Object.ReferenceEquals(m1, d1))  
   End Sub
End Module

Public Class Dog
   ' Public field.
   Public Breed As String
   
   ' Class constructor.
   Public Sub New(dogBreed As String)
      Me.Breed = dogBreed
   End Sub

   Public Overrides Function Equals(obj As Object) As Boolean
      If obj Is Nothing OrElse Not typeof obj Is Dog Then
         Return False
      Else
         Return Me.Breed = CType(obj, Dog).Breed
      End If   
   End Function
   
   Public Overrides Function GetHashCode() As Integer
      Return Me.Breed.GetHashCode()
   End Function
   
   Public Overrides Function ToString() As String
      Return Me.Breed
   End Function
End Class
' The example displays the following output:
'       null = null: True
'       null Reference Equals null: True
'       
'       Great Pyrenees = Great Pyrenees: True
'       Great Pyrenees Reference Equals Great Pyrenees: True
'       
'       Alaskan Malamute = Alaskan Malamute: True
'       Alaskan Malamute Reference Equals Alaskan Malamute: False
'       
'       Alaskan Malamute = Dalmation: False
'       Alaskan Malamute Reference Equals Dalmation: False

Commenti

Il metodo Equals(Object, Object) statico indica se due oggetti , e , sono objA objB uguali. Consente inoltre di testare gli oggetti il cui valore è Null per l'uguaglianza. Confronta e per objA objB l'uguaglianza come indicato di seguito:

  • Determina se i due oggetti rappresentano lo stesso riferimento all'oggetto. In caso contrario, il metodo restituisce true . Questo test equivale a chiamare il ReferenceEquals metodo . Inoltre, se sia objA che objB sono null, il metodo restituisce true .

  • Determina se o objA objB è null. In caso contrario, restituisce false .

  • Se i due oggetti non rappresentano lo stesso riferimento all'oggetto e nessuno dei due è Null, chiama objA . Equals ( objB ) e restituisce il risultato. Questo significa che se objA esegue l'override Object.Equals(Object) del metodo , viene chiamato questo override.

Vedi anche

Si applica a