Questo articolo è stato tradotto automaticamente. Per visualizzare l'articolo in inglese, selezionare la casella di controllo Inglese. È possibile anche visualizzare il testo inglese in una finestra popup posizionando il puntatore del mouse sopra il testo.
Traduzione
Inglese

Metodo Object.Equals (Object)

 

Data di pubblicazione: ottobre 2016

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

Spazio dei nomi:   System
Assembly:  mscorlib (in mscorlib.dll)

public virtual bool Equals(
	object obj
)

Parametri

obj
Type: System.Object

Oggetto da confrontare con l'oggetto corrente.

Valore restituito

Type: System.Boolean

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

Il tipo di confronto tra l'istanza corrente e obj parametro varia a seconda se l'istanza corrente è un tipo riferimento o un tipo di valore.

  • Se l'istanza corrente è un tipo riferimento, il Equals(Object) metodo verifica l'uguaglianza di riferimento e una chiamata al Equals(Object) equivale a una chiamata al metodo di ReferenceEquals metodo. L'uguaglianza dei riferimenti significa che le variabili di oggetto che vengono confrontate fanno riferimento allo stesso oggetto. Nell'esempio seguente viene illustrato il risultato di tale confronto. Definisce un Person (classe), che è un tipo riferimento, e chiama il Person costruttore della classe per creare un'istanza di due nuovi Person oggetti, person1a e person2, che hanno lo stesso valore. Assegna inoltre person1a a un'altra variabile di oggetto, person1b. Come illustrato nell'esempio, l'output person1a e person1b sono uguali, in quanto fanno riferimento allo stesso oggetto. Tuttavia, person1a e person2 non sono 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
    
  • Se l'istanza corrente è un tipo valore, il Equals(Object) metodo verifica l'uguaglianza di valore. L'uguaglianza di valori indica quanto segue:

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

      using System;
      
      public class Example
      {
         public static void Main()
         {
            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
      
    • I valori dei campi pubblici e privati di due oggetti sono uguali. Nell'esempio seguente verifica l'uguaglianza di valori. Definisce un Person struttura, ovvero un tipo di valore, e chiama il Person costruttore della classe per creare un'istanza di due nuovi Person oggetti, person1 e person2, che hanno lo stesso valore. Come illustrato nell'output dell'esempio, anche se le due variabili oggetto fare riferimento a oggetti diversi, person1 e person2 sono uguali perché hanno lo stesso valore per privato personName campo.

      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
      

Poiché il Object classe è la classe base per tutti i tipi in .NET Framework, il Object.Equals(Object) metodo fornisce il confronto di uguaglianza predefinito per tutti gli altri tipi. Tuttavia, tipi spesso eseguono l'override di Equals metodo per implementare l'uguaglianza di valori. Per ulteriori informazioni, vedere le note per i chiamanti e note per le sezioni gli eredi.

Quando si chiama il Equals(Object) overload del metodo in una classe di Windows Runtime, fornisce il comportamento predefinito per le classi che non esegue l'override Equals(Object). Ciò fa parte del supporto fornito da .NET Framework per Windows Runtime (vedere Supporto .NET Framework per applicazioni Windows Store e Windows Runtime. Classi di Windows Runtime non ereditano Objecte non implementano un Equals(Object)metodo. Tuttavia, sembrano disporre ToString, Equals(Object), e GetHashCode metodi quando utilizzarle nel codice c# o Visual Basic e .NET Framework fornisce il comportamento predefinito per questi metodi.

System_CAPS_noteNota

Windows Runtimele classi che vengono scritti in c# o Visual Basic possono eseguire l'override di Equals(Object) overload del metodo.

Spesso override dalle classi derivate di Object.Equals(Object) metodo per implementare l'uguaglianza di valori. Inoltre, i tipi forniscono spesso anche un overload fortemente tipizzato aggiuntivo per il Equals (metodo), in genere mediante l'implementazione di IEquatable<T> interfaccia. Quando si chiama il Equals metodo per verificare l'uguaglianza, è necessario conoscere se l'istanza corrente sostituisce Object.Equals e comprendere la modalità di una determinata chiamata a un Equals metodo viene risolto. In caso contrario, è possibile eseguire un test di uguaglianza che è diverso da quelli desiderati e il metodo può restituire un valore imprevisto.

Nell'esempio seguente viene illustrato questo concetto. Crea un'istanza di tre StringBuilder gli oggetti con stringhe identiche e quindi imposta su quattro chiamate a Equals metodi. Il primo metodo di chiamata restituisce truee la restituzione di tre rimanenti 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

Nel primo caso, l'oggetto fortemente tipizzato StringBuilder.Equals(StringBuilder) overload del metodo che verifica l'uguaglianza di valore, viene chiamato. Poiché le stringhe assegnate ai due StringBuilder oggetti sono uguali, il metodo restituisce true. Tuttavia, StringBuilder non esegue l'override Object.Equals(Object). Per questo motivo, quando il StringBuilder oggetto viene eseguito il cast a un Object, quando un StringBuilder istanza viene assegnata a una variabile di tipo Objecte quando il Object.Equals(Object, Object) metodo vengono passati due StringBuilder oggetti, il valore predefinito Object.Equals(Object) metodo viene chiamato. Poiché StringBuilder è un tipo riferimento, questa opzione equivale a passando i due StringBuilder oggetti per il ReferenceEquals (metodo). Anche se tutte e tre StringBuilder gli oggetti contengono stringhe identiche, fare riferimento a tre oggetti distinti. Di conseguenza, questi tre chiamate al metodo restituito false.

È possibile confrontare l'oggetto corrente e un altro oggetto per l'uguaglianza dei riferimenti chiamando il ReferenceEquals metodo. In Visual Basic, è inoltre possibile utilizzare il is (parola chiave) (ad esempio, If Me Is otherObject Then ...).

Quando si definisce un tipo personalizzato, tale tipo eredita funzionalità definite dal Equals metodo del tipo di base. La tabella seguente elenca l'implementazione predefinita del Equals metodo per le principali categorie di tipi in .NET Framework.

Categoria di tipi

Uguaglianza definito da

Commenti

Classe derivata direttamente daObject

Object.Equals(Object)

Uguaglianza dei riferimenti; equivale a chiamare Object.ReferenceEquals.

Struttura

ValueType.Equals

Uguaglianza di valori; confronto diretto byte per byte o campo per campo tramite reflection.

Enumerazione

Enum.Equals

I valori devono avere lo stesso tipo di enumerazione e lo stesso valore sottostante.

delegate

MulticastDelegate.Equals

I delegati devono avere lo stesso tipo con elenchi chiamate identici.

Interfaccia

Object.Equals(Object)

Uguaglianza dei riferimenti.

Per un tipo valore, è necessario sempre eseguire l'override Equals, perché verifica l'uguaglianza che si basa sulla reflection offre un peggioramento delle prestazioni. È inoltre possibile sostituire l'implementazione predefinita di Equals per i tipi di riferimento per verificare l'uguaglianza di valore anziché l'uguaglianza di riferimento e di definire il significato esatto di uguaglianza. Tali implementazioni di Equals restituire true se i due oggetti hanno lo stesso valore, anche se non sono la stessa istanza. Responsabile dell'implementazione del tipo decide cosa si intende un valore di oggetto, ma in genere alcuni o tutti i dati archiviati nelle variabili di istanza dell'oggetto. Ad esempio, il valore di un String oggetti si basano sui caratteri della stringa; il String.Equals(Object) override dei metodi il Object.Equals(Object) per restituire true per le due istanze che contengono gli stessi caratteri nello stesso ordine di stringa.

Nell'esempio seguente viene illustrato come eseguire l'override di Object.Equals(Object) metodo per verificare l'uguaglianza di valore. Esegue l'override di Equals metodo per la Person classe. Se Person accettato l'implementazione della classe di base di uguaglianza, due Person oggetti sarebbero uguali solo se viene fatto un singolo oggetto. Tuttavia, in questo caso, due Person oggetti sono uguali se hanno lo stesso valore per il Person.Id proprietà.

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

Oltre a sostituire Equals, è possibile implementare il IEquatable<T> interfaccia per fornire un test fortemente tipizzata per verificarne l'uguaglianza.

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

  • x.Equals(x)Restituisce true, tranne nei casi in cui tipi a virgola mobile. Vedere ISO/IEC/IEEE 60559:2011, IT - sistemi microprocessore - aritmetica a virgola mobile.

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

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

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

  • Le chiamate successive a x.Equals(y) restituire lo stesso valore, purché gli oggetti a cui fa riferimento x e y non vengono modificati.

  • x.Equals(null) restituisce false.

Le implementazioni di Equals non devono generare eccezioni; restituiscono sempre un valore. Ad esempio, se obj è null, Equals metodo dovrebbe restituire false anziché generare un ArgumentNullException.

Seguire queste linee guida quando si esegue l'override Equals(Object):

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

  • I tipi che eseguono l'override Equals(Object) deve anche eseguire l'override GetHashCode; in caso contrario, le tabelle hash potrebbero non funzionare correttamente.

  • È consigliabile implementare la IEquatable<T> interfaccia per supportare fortemente tipizzata verifica l'uguaglianza. Il IEquatable<T>.Equals implementazione debba restituire risultati coerenti con Equals.

  • Se il linguaggio di programmazione supporta l'overload degli operatori e si esegue l'overload di operatore di uguaglianza per un determinato tipo, è inoltre necessario eseguire l'override di Equals(Object) per restituire lo stesso risultato dell'operatore di uguaglianza. Ciò consente di garantire che il codice della libreria di classe che utilizza Equals (ad esempio ArrayList e Hashtable) si comporta in modo che sia coerenza con il modo in cui viene utilizzato l'operatore di uguaglianza dal codice dell'applicazione.

Applicano le linee guida seguenti per eseguire l'override Equals(Object) per un tipo di riferimento:

  • Eseguire l'override Equals se la semantica del tipo è basata sul fatto che il tipo rappresenta dei valori.

  • La maggior parte dei tipi di riferimento devono non eseguire l'overload dell'operatore di uguaglianza, anche se hanno la precedenza su Equals. Tuttavia, se si implementa un tipo di riferimento destinato alla semantica dei valori, ad esempio un numero complesso di tipo, è necessario eseguire l'override dell'operatore di uguaglianza.

  • Eseguire l'override di Equals su un tipo di riferimento modificabile. In questo modo si esegue l'override Equals richiede anche eseguire l'override di GetHashCode (metodo), come descritto nella sezione precedente. Ciò significa che è possibile modificare il codice hash di un'istanza di un tipo di riferimento modificabile durante la sua durata, che può causare l'oggetto andranno persi in una tabella hash.

Applicano le linee guida seguenti per eseguire l'override Equals(Object) per un tipo di valore:

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

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

  • È necessario implementare la IEquatable<T> interfaccia. Chiamare l'oggetto fortemente tipizzato IEquatable<T>.Equals metodo consente di evitare la conversione boxing di obj argomento.

Nell'esempio seguente un Point che esegue l'override di Equals metodo per fornire l'uguaglianza di valori e un Point3D classe che deriva da Point. Poiché Point esegue l'override Object.Equals(Object) per verificare l'uguaglianza di valore, il Object.Equals(Object) non viene chiamato. Tuttavia, Point3D.Equals chiamate Point.Equals perché Point implementa Object.Equals(Object) in modo che fornisce l'uguaglianza di 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

The Point.Equals method checks to make sure that the obj argument is not null and that it references an instance of the same type as this object. If either check fails, the method returns false.

The Point.Equals method calls the M:System.Object.GetType method to determine whether the run-time types of the two objects are identical. If the method used a check of the form obj is Point in C# or TryCast(obj, Point) in Visual Basic, the check would return true in cases where obj is an instance of a derived class of Point, even though obj and the current instance are not of the same run-time type. Having verified that both objects are of the same type, the method casts obj to type Point and returns the result of comparing the instance fields of the two objects.

In Point3D.Equals, the inherited Point.Equals method, which overrides M:System.Object.Equals(System.Object), is invoked before anything else is done. Because Point3D is a sealed class (NotInheritable in Visual Basic), a check in the form obj is Point in C# or TryCast(obj, Point) in Visual Basic is adequate to ensure that obj is a Point3D object. If it is a Point3D object, it is cast to a Point object and passed to the base class implementation of M:System.Object.Equals(System.Object). Only when the inherited Point.Equals method returns true does the method compare the z instance fields introduced in the derived class.

L'esempio seguente definisce un Rectangle classe che implementa internamente un rettangolo come due Point oggetti. Il Rectangle esegue l'override anche di classe Object.Equals(Object) per fornire l'uguaglianza.

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

Alcuni linguaggi come c# e Visual Basic supportano l'overload degli operatori. Quando un tipo esegue l'overload dell'operatore di uguaglianza, deve anche eseguire l'override di Equals(Object) metodo per fornire la stessa funzionalità. Questa operazione viene in genere eseguita mediante la scrittura di Equals(Object) metodo in termini dell'operatore di uguaglianza, 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

Because Complex is a value type, it cannot be derived from. Therefore, the override to M:System.Object.Equals(System.Object) method need not call M:System.Object.GetType to determine the precise run-time type of each object, but can instead use the is operator in C# or the TypeOf operator in Visual Basic to check the type of the obj parameter.

Universal Windows Platform
Disponibile da 8
.NET Framework
Disponibile da 1.1
Libreria di classi portabile
Supportato in: piattaforme .NET portabili
Silverlight
Disponibile da 2.0
Windows Phone Silverlight
Disponibile da 7.0
Windows Phone
Disponibile da 8.1
Torna all'inizio
Mostra: