Exporter (0) Imprimer
Développer tout
Cet article a fait l'objet d'une traduction automatique. Déplacez votre pointeur sur les phrases de l'article pour voir la version originale de ce texte. Informations supplémentaires.
Traduction
Source
1 sur 1 ont trouvé cela utile - Évaluez ce sujet

Object.Equals, méthode (Object)

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 avec l'objet actif.

Valeur de retour

Type : System.Boolean
true si l'objet spécifié est égal à l'objet actif ; sinon, false.

Type de comparaison entre l'instance actuelle et le paramètre obj dépend si l'instance actuelle est un type référence ou un type valeur.

  • Si l'instance actuelle est un type référence, les tests de méthode Equals(Object) pour l'égalité des références, et un appel à la méthode Equals(Object) équivaut à un appel à la méthode ReferenceEquals. Référencez l'égalité signifie que les variables objets qui sont comparées renvoient au même objet. L'exemple suivant montre le résultat de cette comparaison. Il définit une classe Person, qui est un type référence, puis appelle le constructeur de classe Person pour instancier deux nouveaux objets Person, person1a et person2, qui ont la même valeur. Il assigne également un person1a à une autre variable objet, person1b. Comme la sortie de l'exemple, person1a et person1b sont égaux car ils référencent le même objet. Toutefois, person1a et person2 ne sont pas identiques, bien qu'ils aient 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, les tests de méthode Equals(Object) d'égalité des valeurs. L'égalité des valeurs signifie ce qui suit :

    • Les deux objets sont du même type. Comme le montre l'exemple suivant, un objet Byte qui a la valeur 12 n'est pas un objet Int32 qui a la valeur 12, car les deux objets ont différents types 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 de l'égalité des valeurs. Il définit une structure d'un Person, un type valeur, et appelle le constructeur de classe Person pour instancier deux nouveaux objets Person, person1 et person2, qui ont la même valeur. Comme la sortie des exemple, bien que les deux variables objets font référence à des objets, person1 et person2 sont égales car ils ont la même valeur pour le champ personName privé.

      
      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
      
      
      

La classe Object est la classe de base de tous types .NET Framework, la méthode Object.Equals(Object) fournit la comparaison d'égalité par défaut pour tous les autres types. Toutefois, les types substituent souvent la méthode Equals pour implémenter l'égalité des valeurs. Pour plus d'informations, consultez les remarques sur les appelants et les remarques sur des sections d'héritiers.

Remarques pour Windows Runtime

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

RemarqueRemarque

les classes d'Windows Runtime écrites en C# ou Visual Basic peuvent substituer la surcharge de méthode Equals(Object).

Remarques pour les appelants

Les classes dérivées substituent fréquemment la méthode Object.Equals(Object) pour implémenter l'égalité des valeurs. En outre, les types fournissent aussi fréquemment une surcharge fortement typée supplémentaire à la méthode Equals, généralement en implémentant l'interface IEquatable<T>. Lorsque vous appelez la méthode Equals pour tester l'égalité, vous devez savoir si l'instance actuelle substitue Object.Equals et incluez comment un appel particulier à une méthode Equals est résolu. Sinon, vous pouvez effectuer un test d'égalité différente de ce que vous attendu, et la méthode pouvez retourner une valeur inattendue.

L'exemple suivant illustre cette situation. Il instancie trois objets StringBuilder avec les chaînes identiques, puis fait quatre appels aux méthodes Equals. Le premier appel de méthode retourne true, ainsi que d'autres trois retournent 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, la surcharge fortement typée de méthode StringBuilder.Equals(StringBuilder), qui détermine l'égalité des valeurs, est appelée. Les chaînes assignées aux deux objets StringBuilder sont égales, la méthode retourne true. Toutefois, StringBuilder ne substitue pas Object.Equals(Object). Pour cette raison, lorsque l'objet StringBuilder est casté en Object, lorsqu'une instance d'StringBuilder est assignée à une variable de type Object, et lorsque la méthode Object.Equals(Object, Object) est passée deux objets StringBuilder, la méthode Object.Equals(Object) par défaut est appelé. Comme StringBuilder est un type référence, il est équivalent à passer les deux objets StringBuilder à la méthode ReferenceEquals. Bien que les trois objets StringBuilder contienne les chaînes identiques, ils font référence à trois objets distincts. Par conséquent, ces trois appels de méthode retournent false.

Vous pouvez comparer l'objet actif à un autre objet pour tester l'égalité de référence en appelant la méthode ReferenceEquals. En Visual Basic, vous pouvez également utiliser le mot clé is (par exemple, If Me Is otherObject Then ...).

Remarques à l'attention des héritiers

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

Catégorie de type

Égalité définie par

Commentaires

Classe dérivée directement de Object

Object.Equals(Object)

Référencez l'égalité ; équivalent à appeler Object.ReferenceEquals.

Structure

ValueType.Equals

Égalité de valeur ; comparaison directe par octet ou comparaison de champ-par- champ en utilisant la réflexion.

Énumération

Enum.Equals

Les valeurs doivent avoir le même type énumération et la même valeur sous-jacente.

Délégué

MulticastDelegate.Equals

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

Interface

Object.Equals(Object)

Référencez l'égalité.

Pour un type valeur, vous devez toujours substituer Equals, parce que les tests d'égalité qui reposent sur des performances médiocres offrent de réflexion. Vous pouvez également substituer l'implémentation par défaut de Equals pour les types référence déterminent l'égalité des valeurs au lieu de l'égalité de référence et de définir la signification exacte de l'égalité des valeurs. Ces implémentations de retour true d'Equals si les deux objets ont la même valeur, même s'ils ne sont pas la même instance. L'implémenteur de type détermine ce qui constitue la valeur d'un objet, mais il en est généralement ou toutes les données stockées dans des variables d'instance de l'objet. Par exemple, la valeur d'un objet String est basé sur les caractères de la chaîne ; la méthode String.Equals(Object) substitue la méthode Object.Equals(Object) pour retourner true pour deux instances quelconques de chaîne qui contiennent les mêmes caractères dans le même ordre.

L'exemple suivant montre comment substituer la méthode Object.Equals(Object) pour déterminer l'égalité des valeurs. Il substitue la méthode Equals pour la classe Person. Si Person acceptait son implémentation de la classe de base d'égalité, deux objets Person sont égaux uniquement s'ils référençaient un objet unique. Toutefois, dans ce cas, deux objets Person sont égaux s'ils ont la même valeur pour la propriété 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


En plus de substituer Equals, vous pouvez implémenter l'interface IEquatable<T> pour fournir un test fortement typé d'égalité.

Les instructions suivantes doivent avoir la valeur true pour toutes les implémentations de la méthode Equals(Object). Dans la liste, x, y, et z représentent les références d'objets qui ne sont pas null.

  • x.Equals(x) retourne true, sauf dans des situations qui impliquent des types à virgule flottante. Consultez 60559:2011 d'ISO/IEC/IEEE, technologie d'informations -- Systèmes de processeur -- Calcul à virgule flottante.

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

  • x.Equals(y) retourne true si x et y sont NaN.

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

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

  • x.Equals(null) retourne false.

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

Suivez ces indications en substituant Equals(Object):

  • Les types qui implémentent IComparable doivent substituer Equals(Object).

  • Les types que la substitution Equals(Object) doit substituer GetHashCode; sinon, les tables de hachage ne pas fonctionner correctement.

  • Vous devez envisager d'implémenter l'interface IEquatable<T> pour prendre en charge les tests fortement typés pour l'égalité. Votre implémentation d'IEquatable<T>.Equals si les résultats compatibles avec Equals.

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

bsc2ak47.collapse_all(fr-fr,VS.110).gifIndications pour les types référence

Les indications suivantes s'appliquent à substituer Equals(Object) pour un type référence :

  • Envisagez le remplacement d'Equals si la sémantique du type sont basés sur le fait que le type représente certaines valeurs.

  • La plupart des types référence ne doivent pas surcharger l'opérateur d'égalité, même s'ils substituent la méthode Equals. Cependant, si vous implémentez un type référence qui doit avoir une sémantique de valeur, telle qu'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 Equals requiert que vous substituez également la méthode GetHashCode, comme décrit 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, qui peut provoquer l'objet à perdre dans une table de hachage.

bsc2ak47.collapse_all(fr-fr,VS.110).gifIndications pour les types valeur

Les indications suivantes s'appliquent à substituer 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). L'implémentation d'Equals(Object) fournie par ValueType effectue une comparaison octet par octet pour les types valeur dont les champs sont tous les types valeur, mais elle utilise la réflexion pour effectuer une comparaison de champ-par- champ des types valeur dont les champs sont des types référence.

  • Si vous substituez Equals et la surcharge d'opérateur de prises en charge linguistique du développement, vous devez surcharger l'opérateur d'égalité.

  • Vous devez implémenter l'interface IEquatable<T>. L'appel de la méthode IEquatable<T>.Equals fortement typée évite de définir l'argument obj.

L'exemple suivant présente une classe Point qui substitue la méthode Equals pour fournir l'égalité des valeurs, une classe Point3D dérivée d'Point. Comme Point substitue Object.Equals(Object) pour déterminer l'égalité des valeurs, la méthode Object.Equals(Object) 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


La méthode Point.Equals vérifie que l'argument obj n'est pas null et qu'il référence une instance du même type que l'objet. Si l'un ou l'autre contrôle échoue, la méthode retourne false.

La méthode Point.Equals appelle la méthode GetType pour déterminer si les types d'exécution des deux objets sont identiques. Si la méthode utilise un contrôle de en C# ou d'TryCast(obj, Point) d'obj is Point de formulaire en Visual Basic, le contrôle retourne true dans les cas où obj est une instance d'une classe dérivée de Point, bien obj et l'instance actuelle ne soient pas du même type d'exécution. Après avoir vérifié que les deux objets sont du même type, la méthode effectue obj au type Point et retourne le résultat de comparer les champs d'instance des deux objets.

Dans Point3D.Equals, la méthode Point.Equals héritée, qui substitue Object.Equals(Object), est appelée avant tout autre élément soit effectué. Comme Point3D est une classe sealed (NotInheritable en Visual Basic), un contrôle dans en C# d'obj is Point de formulaire ou TryCast(obj, Point) en Visual Basic est suffisant pour vérifier qu' obj est un objet Point3D. Si c'est un objet Point3D, il est casté à un objet Point et passé à l'implémentation de la classe de base d'Equals. Lorsque retourne hérités true de méthode Point.Equals fait la méthode comparez les champs d'instance d'z introduites dans la classe dérivée.

L'exemple suivant définit une classe Rectangle qui implémente en interne un rectangle comme deux objets Point. La classe Rectangle substitue également Object.Equals(Object) pour prédire 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. Si un type surcharge l'opérateur d'égalité, il doit également substituer la méthode Equals(Object) pour fournir les mêmes fonctionnalités. En général, ceci est réalisé en écrivant la méthode Equals(Object) sous la forme de l'opérateur d'égalité surchargé, comme dans l'exemple de code 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


Comme Complex est un type valeur, il ne peut pas être dérivé. Par conséquent, la substitution de la méthode Equals(Object) n'a pas besoin d'appeler GetType pour déterminer le type d'exécution exact de chaque objet, mais peut utiliser à la place en C# opérateur d'is ou l'opérateur TypeOf en Visual Basic pour vérifier le type du paramètre obj.

.NET Framework

Pris en charge dans : 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Pris en charge dans : 4, 3.5 SP1

Bibliothèque de classes portable

Pris en charge dans : Bibliothèque de classes portable

.NET pour les applications du Windows Store

Pris en charge dans : Windows 8

Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (rôle principal du serveur non pris en charge), Windows Server 2008 R2 (rôle principal du serveur pris en charge avec SP1 ou version ultérieure ; Itanium non pris en charge)

Le .NET Framework ne prend pas en charge toutes les versions de chaque plateforme. Pour obtenir la liste des versions prises en charge, consultez Configuration requise du .NET Framework.

Ajouts de la communauté

AJOUTER
Afficher:
© 2014 Microsoft. Tous droits réservés.