Cet article a fait l’objet d’une traduction automatique. Pour afficher l’article en anglais, activez la case d’option Anglais. Vous pouvez également afficher le texte anglais dans une fenêtre contextuelle en faisant glisser le pointeur de la souris sur le texte traduit.
Traduction
Anglais

Object.Equals méthode (Object)

 

Date de publication : novembre 2016

Détermine si l'objet spécifié est identique à l'objet actuel.

Espace de noms:   System
Assembly:  mscorlib (dans mscorlib.dll)

public virtual bool Equals(
	object obj
)

Paramètres

obj
Type: System.Object

Objet à comparer à l'objet actuel.

Valeur de retour

Type: System.Boolean

true si l'objet spécifié est égal à l'objet actuel ; sinon, false.

Le type de comparaison entre l’instance actuelle et la obj paramètre varie selon que l’instance actuelle est un type référence ou un type valeur.

  • Si l’instance actuelle est un type référence, le Equals(Object) méthode teste l’égalité de référence et un appel à la Equals(Object) méthode est équivalente à un appel à la ReferenceEquals (méthode). L’égalité des références signifie que les variables d’objet qui sont comparées font référence au même objet. L’exemple suivant illustre le résultat de ce type de comparaison. Il définit un Person (classe), qui est un type référence, et appelle le Person constructeur de classe à instancier deux nouveaux Person objets, person1a et person2, qui ont la même valeur. Il affecte également person1a à une autre variable objet, person1b. Comme la sortie de l’exemple, person1a et person1b sont égales, car elles référencent le même objet. Toutefois, person1a et person2 ne sont pas égales, même si elles ont la même valeur.

    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
    
  • Si l’instance actuelle est un type valeur, le Equals(Object) méthode teste l’égalité de valeur. L’égalité des valeurs signifie que les éléments suivants :

    • Les deux objets sont du même type. Comme le montre l’exemple suivant, un Byte objet qui a la valeur 12 n’est pas égale un Int32 objet qui a une valeur de 12, car les deux objets ont des types différents d’exécution.

      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
      
    • Les valeurs des champs publics et privés des deux objets sont égales. L’exemple suivant teste l’égalité des valeurs. Il définit un Person structure, qui est un type valeur, et appelle le Person constructeur de classe à instancier deux nouveaux Person objets, person1 et person2, qui ont la même valeur. Comme le montre la sortie de l’exemple, bien que les deux variables objets font référence à des objets différents, person1 et person2 sont égaux, car ils ont la même valeur pour privé personName champ.

      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
      

Étant donné que la Object est la classe de base pour tous les types dans le .NET Framework, la Object.Equals(Object) méthode fournit la comparaison d’égalité par défaut pour tous les autres types. Toutefois, les types souvent remplacer le Equals méthode pour implémenter l’égalité des valeurs. Pour plus d’informations, consultez les Notes pour les appelants et les Notes pour les sections de l’attention des héritiers.

Lorsque vous appelez le Equals(Object) la surcharge de méthode sur une classe dans le Windows Runtime, il fournit le comportement par défaut pour les classes qui ne remplacent pas Equals(Object). Ceci fait partie du support que le .NET Framework fournit pour Windows Runtime (voir Prise en charge .NET Framework pour les applications Windows Store et Windows Runtime). Classes de la Windows Runtime n’héritent pas Objectet n’implémentent pas actuellement un Equals(Object)(méthode). Toutefois, ils semblent avoir ToString, Equals(Object), et GetHashCode méthodes lorsque vous les utilisez dans votre code c# ou Visual Basic et le .NET Framework fournit le comportement par défaut pour ces méthodes.

System_CAPS_noteRemarque

Windows Runtimeles classes qui sont écrits en c# ou Visual Basic peuvent substituer la Equals(Object) surcharge de méthode.

Les classes dérivées remplacer fréquemment le Object.Equals(Object) méthode pour implémenter l’égalité des valeurs. En outre, les types fournissent aussi fréquemment une surcharge supplémentaire fortement typée pour le Equals méthode, généralement en implémentant le IEquatable<T> interface. Lorsque vous appelez le Equals méthode pour tester l’égalité, vous devez savoir si l’instance actuelle se substitue à Object.Equals et comprendre comment un appel particulier à un Equals méthode est résolue. Sinon, vous effectuer un test d’égalité qui est différente de ceux que vous aviez prévus, et la méthode peut retourner une valeur inattendue.

L'exemple suivant illustre cette situation. Il instancie trois StringBuilder objets avec des chaînes identiques, puis appelle quatre Equals méthodes. La première méthode d’appel retourne trueet le retour de trois autres 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

Dans le premier cas, fortement typé StringBuilder.Equals(StringBuilder) surcharge de méthode qui teste l’égalité des valeurs, est appelée. Étant donné que les chaînes attribué aux deux StringBuilder objets sont égaux, la méthode retourne true. Toutefois, StringBuilder ne remplace pas Object.Equals(Object). Pour cette raison, lorsque le StringBuilder objet est converti en un Object, lorsque un StringBuilder instance est assignée à une variable de type Objectet à quel moment le Object.Equals(Object, Object) méthode est passée de deux StringBuilder objets, la valeur par défaut Object.Equals(Object) méthode est appelée. Étant donné que StringBuilder est un type référence, cela équivaut à passer les deux StringBuilder des objets sur le ReferenceEquals (méthode). Bien que les trois StringBuilder objets contiennent des chaînes identiques, ils font référence à trois objets distincts. Par conséquent, ces trois appels de méthode retour false.

Vous pouvez comparer l’objet actuel à un autre objet pour égalité des références en appelant le ReferenceEquals (méthode). En Visual Basic, vous pouvez également utiliser le is (mot clé) (par exemple, If Me Is otherObject Then ...).

Lorsque vous définissez votre propre type, ce type hérite des fonctionnalités définies par le Equals méthode de son type de base. Le tableau suivant répertorie l’implémentation par défaut de la Equals méthode pour les principales catégories de types dans le .NET Framework.

Catégorie de type

Égalité défini par

Commentaires

Classe dérivée directement à partir deObject

Object.Equals(Object)

Égalité de référence ; équivalent à l’appel Object.ReferenceEquals.

Structure

ValueType.Equals

Égalité des valeurs ; une comparaison octet par octet directe ou comparaison de champ par champ à l’aide de la réflexion.

Énumération

Enum.Equals

Valeurs doivent avoir le même type d’énumération et la même valeur sous-jacente.

delegate

MulticastDelegate.Equals

Les délégués doivent avoir le même type avec les listes d’appel identiques.

Interface

Object.Equals(Object)

Égalité des références.

Pour un type valeur, vous devez toujours remplacer Equals, car les tests d’égalité qui reposent sur la réflexion offrent des performances médiocres. Vous pouvez également substituer l’implémentation par défaut de Equals pour les types de référence pour tester l’égalité des valeurs au lieu de l’égalité des références et pour définir la signification précise de l’égalité des valeurs. De telles implémentations de Equals retourner true si les deux objets ont la même valeur, même s’ils ne sont pas la même instance. L’implémenteur du type décide ce qui constitue la valeur d’un objet, mais il est généralement tout ou partie des données stockées dans les variables d’instance de l’objet. Par exemple, la valeur d’un String objet est basé sur les caractères de la chaîne ; le String.Equals(Object) substitutions de méthode le Object.Equals(Object) retour de méthode true pour les deux instances contiennent les mêmes caractères dans le même ordre de chaîne.

L’exemple suivant montre comment substituer la Object.Equals(Object) méthode pour tester l’égalité des valeurs. Il remplace le Equals méthode pour la Person classe. Si Person accepté son implémentation de la classe de base de l’égalité, deux Person objets serait égales uniquement si elles référencé un objet unique. Toutefois, dans ce cas, deux Person objets sont égales si elles ont la même valeur pour le Person.Id propriété.

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

Outre l’écrasement Equals, vous pouvez implémenter la IEquatable<T> interface afin de fournir un test fortement typé pour l’égalité.

Les instructions suivantes doivent être remplies pour toutes les implémentations de la Equals(Object) (méthode). Dans la liste, x, y, et z représentent des références d’objet qui ne sont pas null.

  • x.Equals(x)Retourne true, sauf dans les scénarios qui impliquent des types à virgule flottante. Voir ISO/IEC/IEEE 60559:2011, informatique--microprocesseur systèmes--arithmétique à virgule flottante.

  • x.Equals(y)Retourne la même valeur que y.Equals(x).

  • x.Equals(y)Retourne true si les deux x et y sont NaN.

  • Si (x.Equals(y) && y.Equals(z)) retourne true, puis x.Equals(z) retourne true.

  • Les appels successifs à x.Equals(y) retournent la même valeur tant que les objets référencés par x et y ne sont pas modifiées.

  • x.Equals(null) retourne false.

Les implémentations de Equals ne doit pas lever d’exceptions ; ils doivent toujours retourner une valeur. Par exemple, si obj est null, le Equals méthode doit retourner false au lieu de lever une ArgumentNullException.

Suivez ces recommandations lors de la substitution Equals(Object):

  • Les types qui implémentent IComparable doit remplacer Equals(Object).

  • Types qui substituent Equals(Object) doit également substituer GetHashCode; sinon, les tables de hachage peut ne pas fonctionneront correctement.

  • Vous devez envisager d’implémenter le IEquatable<T> interface pour prendre en charge fortement typé vérifie l’égalité. Votre IEquatable<T>.Equals implémentation doit retourner des résultats cohérents avec Equals.

  • Si votre langage de programmation prend en charge la surcharge d’opérateur et si vous surchargez l’opérateur d’égalité pour un type donné, vous devez également substituer la Equals(Object) méthode pour retourner le même résultat que l’opérateur d’égalité. Cela permet de garantir que code de bibliothèque de classe qui utilise Equals (tel que ArrayList et Hashtable) se comporte de manière cohérente avec le mode d’utilisation de l’opérateur d’égalité par le code d’application.

Les directives suivantes s’appliquent à la substitution de Equals(Object) pour un type référence :

  • Pensez à substituer Equals si la sémantique de type est basée sur le fait que le type représente une ou plusieurs valeurs.

  • La plupart des types référence ne doivent pas surcharger l’opérateur d’égalité, même s’ils substituent Equals. Toutefois, si vous implémentez un type référence qui doit avoir une sémantique de valeur, par exemple un type nombre complexe, vous devez substituer l’opérateur d’égalité.

  • Vous ne devez pas substituer Equals sur un type référence mutable. C’est parce que la substitution de Equals requiert également substituer la GetHashCode méthode, comme indiqué dans la section précédente. Cela signifie que le code de hachage d’une instance d’un type référence mutable peut changer pendant sa durée de vie, ce qui peut entraîner l’objet à être perdues dans une table de hachage.

Les directives suivantes s’appliquent à la substitution de Equals(Object) pour un type valeur :

  • Si vous définissez un type valeur qui inclut un ou plusieurs champs dont les valeurs sont des types référence, vous devez substituer Equals(Object). Le Equals(Object) implémentation fournie par ValueType effectue une comparaison octet par octet pour les types de valeur dont les champs sont tous les types valeur, mais il utilise la réflexion pour effectuer une comparaison de champ par champ de types de valeur dont les champs sont des types référence.

  • Si vous substituez Equals et votre langage de développement prend en charge la surcharge d’opérateur, vous devez surcharger l’opérateur d’égalité.

  • Vous devez implémenter la IEquatable<T> interface. Fortement typées IEquatable<T>.Equals méthode évite de boxing le obj argument.

L’exemple suivant montre un Point classe qui remplace le Equals méthode pour fournir l’égalité des valeurs et un Point3D classe qui est dérivée de Point. Étant donné que Point substitue Object.Equals(Object) pour tester l’égalité des valeurs, le Object.Equals(Object) méthode n’est pas appelée. Toutefois, Point3D.Equals appelle Point.Equals car Point implémente Object.Equals(Object) d’une manière qui fournit l’égalité des valeurs.

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’exemple suivant définit un Rectangle classe qui implémente en interne un rectangle sous forme de deux Point objets. Le Rectangle classe également remplacements Object.Equals(Object) pour fournir l’égalité des valeurs.

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

Certains langages tels que c# et Visual Basic prennent en charge la surcharge d’opérateur. Quand un type surcharge l’opérateur d’égalité, il doit également substituer la Equals(Object) méthode pour fournir les mêmes fonctionnalités. Cela est généralement accomplie en écrivant la Equals(Object) méthode en termes de l’opérateur d’égalité surchargé, comme dans l’exemple suivant.

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.

Plateforme Windows universelle
Disponible depuis 8
.NET Framework
Disponible depuis 1.1
Bibliothèque de classes portable
Pris en charge dans : plateformes .NET portables
Silverlight
Disponible depuis 2.0
Silverlight pour Windows Phone
Disponible depuis 7.0
Windows Phone
Disponible depuis 8.1
Retour au début
Afficher: