Lire en anglais

Partager via


Object.MemberwiseClone Méthode

Définition

Crée une copie superficielle du Objectactuel.

C#
protected object MemberwiseClone();

Retours

Copie superficielle du Objectactuel .

Exemples

L’exemple suivant illustre la méthode MemberwiseClone. Il définit une méthode ShallowCopy qui appelle la méthode MemberwiseClone pour effectuer une opération de copie superficielle sur un objet Person. Il définit également une méthode DeepCopy qui effectue une opération de copie approfondie sur un objet Person.

C#
using System;

public class IdInfo
{
    public int IdNumber;

    public IdInfo(int IdNumber)
    {
        this.IdNumber = IdNumber;
    }
}

public class Person
{
    public int Age;
    public string Name;
    public IdInfo IdInfo;

    public Person ShallowCopy()
    {
        return (Person)MemberwiseClone();
    }

    public Person DeepCopy()
    {
        Person other = (Person)MemberwiseClone();
        other.IdInfo = new IdInfo(IdInfo.IdNumber);
        return other;
    }
}

public class Example
{
    public static void Main()
    {
        // Create an instance of Person and assign values to its fields.
        Person p1 = new()
        {
            Age = 42,
            Name = "Sam",
            IdInfo = new IdInfo(6565)
        };

        // Perform a shallow copy of p1 and assign it to p2.
        Person p2 = p1.ShallowCopy();

        // Display values of p1, p2
        Console.WriteLine("Original values of p1 and p2:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p2 instance values:");
        DisplayValues(p2);

        // Change the value of p1 properties and display the values of p1 and p2.
        p1.Age = 32;
        p1.Name = "Frank";
        p1.IdInfo.IdNumber = 7878;
        Console.WriteLine("\nValues of p1 and p2 after changes to p1:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p2 instance values:");
        DisplayValues(p2);

        // Make a deep copy of p1 and assign it to p3.
        Person p3 = p1.DeepCopy();
        // Change the members of the p1 class to new values to show the deep copy.
        p1.Age = 39;
        p1.Name = "George";
        p1.IdInfo.IdNumber = 8641;
        Console.WriteLine("\nValues of p1 and p3 after changes to p1:");
        Console.WriteLine("   p1 instance values: ");
        DisplayValues(p1);
        Console.WriteLine("   p3 instance values:");
        DisplayValues(p3);
    }

    public static void DisplayValues(Person p)
    {
        Console.WriteLine($"      Name: {p.Name:s}, Age: {p.Age:d}");
        Console.WriteLine($"      Value: {p.IdInfo.IdNumber:d}");
    }
}

/* The example displays the following output:
 * 
 * Original values of p1 and p2:
      p1 instance values:
         Name: Sam, Age: 42
         Value: 6565
      p2 instance values:
         Name: Sam, Age: 42
         Value: 6565

   Values of p1 and p2 after changes to p1:
      p1 instance values:
         Name: Frank, Age: 32
         Value: 7878
      p2 instance values:
         Name: Sam, Age: 42
         Value: 7878

   Values of p1 and p3 after changes to p1:
      p1 instance values:
         Name: George, Age: 39
         Value: 8641
      p3 instance values:
         Name: Frank, Age: 32
         Value: 7878
 */

Dans cet exemple, la propriété Person.IdInfo retourne un objet IdInfo. Comme le montre la sortie de l’exemple, lorsqu’un objet Person est cloné en appelant la méthode MemberwiseClone, l’objet Person cloné est une copie indépendante de l’objet d’origine, sauf qu’ils partagent la même référence d’objet Person.IdInfo. Par conséquent, la modification de la propriété Person.IdInfo du clone modifie la propriété Person.IdInfo de l’objet d’origine. En revanche, lorsqu’une opération de copie approfondie est effectuée, l’objet Person cloné, y compris sa propriété Person.IdInfo, peut être modifié sans affecter l’objet d’origine.

Remarques

La méthode MemberwiseClone crée une copie superficielle en créant un objet, puis en copiant les champs non statiques de l’objet actuel vers le nouvel objet. Si un champ est un type valeur, une copie bit par bits du champ est effectuée. Si un champ est un type référence, la référence est copiée, mais l’objet référencé n’est pas ; par conséquent, l’objet d’origine et son clone font référence au même objet.

Pour illustrer la différence entre une opération de copie profonde et superficielle, considérez un objet appelé X qui référence des objets A et B. Object B, à son tour, référence l’objet C. Une copie superficielle de X crée un objet X2 qui fait également référence à des objets A et B. En revanche, une copie approfondie de X crée un objet X2 qui fait référence aux nouveaux objets A2 et B2, qui sont des copies d’A et B. B2, à son tour, fait référence au nouvel objet C2, qui est une copie de C.

Il existe de nombreuses façons d’implémenter une opération de copie approfondie si l’opération de copie superficielle effectuée par la méthode MemberwiseClone ne répond pas à vos besoins. Il s’agit notamment des éléments suivants :

  • Appelez un constructeur de classe de l’objet à copier pour créer un deuxième objet avec des valeurs de propriété extraites du premier objet. Cela suppose que les valeurs d’un objet sont entièrement définies par son constructeur de classe.
  • Appelez la méthode MemberwiseClone pour créer une copie superficielle d’un objet, puis attribuez de nouveaux objets dont les valeurs sont identiques à l’objet d’origine à toutes les propriétés ou champs dont les valeurs sont des types de référence. La méthode DeepCopy dans l’exemple illustre cette approche.
  • Sérialisez l’objet à copier en profondeur, puis restaurez les données sérialisées dans une variable d’objet différente.
  • Utilisez la réflexion avec récursivité pour effectuer l’opération de copie approfondie.

S’applique à

Produit Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0