Object.MemberwiseClone Methode

Definitie

Hiermee maakt u een ondiepe kopie van de huidige Object.

protected:
 System::Object ^ MemberwiseClone();
protected object MemberwiseClone();
member this.MemberwiseClone : unit -> obj
Protected Function MemberwiseClone () As Object

Retouren

Een ondiep exemplaar van de huidige Object.

Voorbeelden

In het volgende voorbeeld ziet u de MemberwiseClone methode. Hiermee wordt een ShallowCopy methode gedefinieerd waarmee de MemberwiseClone methode wordt aangeroepen om een ondiepe kopieerbewerking uit te voeren op een Person object. Er wordt ook een DeepCopy methode gedefinieerd waarmee een diepe kopieerbewerking op een Person object wordt uitgevoerd.

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
 */
open System

type IdInfo(IdNumber) =
    member val IdNumber = IdNumber with get, set

type Person() =
    [<DefaultValue>]
    val mutable public Age: int
    [<DefaultValue>]
    val mutable public Name: string
    [<DefaultValue>]
    val mutable public IdInfo: IdInfo

    member this.ShallowCopy() =
        this.MemberwiseClone() :?> Person

    member this.DeepCopy() =
       let other = this.MemberwiseClone() :?> Person
       other.IdInfo <- IdInfo this.IdInfo.IdNumber
       other

let displayValues (p: Person) =
    printfn $"      Name: {p.Name:s}, Age: {p.Age:d}"
    printfn $"      Value: {p.IdInfo.IdNumber:d}"

// Create an instance of Person and assign values to its fields.
let p1 = Person()
p1.Age <- 42
p1.Name <- "Sam"
p1.IdInfo <- IdInfo 6565

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

// Display values of p1, p2
printfn "Original values of p1 and p2:"
printfn "   p1 instance values: "
displayValues p1
printfn "   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
printfn "\nValues of p1 and p2 after changes to p1:"
printfn "   p1 instance values: "
displayValues p1
printfn "   p2 instance values:"
displayValues p2

// Make a deep copy of p1 and assign it to p3.
let 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
printfn "\nValues of p1 and p3 after changes to p1:"
printfn "   p1 instance values: "
displayValues p1
printfn "   p3 instance values:"
displayValues p3

// 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
Public Class IdInfo
    Public IdNumber As Integer

    Public Sub New(IdNumber As Integer)
        Me.IdNumber = IdNumber
    End Sub
End Class

Public Class Person
    Public Age As Integer
    Public Name As String
    Public IdInfo As IdInfo

    Public Function ShallowCopy() As Person
        Return DirectCast(MemberwiseClone(), Person)
    End Function

    Public Function DeepCopy() As Person
        Dim other As Person = DirectCast(MemberwiseClone(), Person)
        other.IdInfo = New IdInfo(IdInfo.IdNumber)
        Return other
    End Function
End Class

Module Example
    Public Sub Main()
        ' Create an instance of Person and assign values to its fields.
        Dim p1 As New Person()
        p1.Age = 42
        p1.Name = "Sam"
        p1.IdInfo = New IdInfo(6565)

        ' Perform a shallow copy of p1 and assign it to p2.
        Dim p2 As Person = 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)
        Console.WriteLine()

        ' 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("Values of p1 and p2 after changes to p1:")
        Console.WriteLine("   p1 instance values: ")
        DisplayValues(p1)
        Console.WriteLine("   p2 instance values:")
        DisplayValues(p2)
        Console.WriteLine()

        ' Make a deep copy of p1 and assign it to p3.
        Dim p3 As Person = 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("Values of p1 and p3 after changes to p1:")
        Console.WriteLine("   p1 instance values: ")
        DisplayValues(p1)
        Console.WriteLine("   p3 instance values:")
        DisplayValues(p3)
    End Sub

    Public Sub DisplayValues(p As Person)
        Console.WriteLine("      Name: {0:s}, Age: {1:d}", p.Name, p.Age)
        Console.WriteLine("      Value: {0:d}", p.IdInfo.IdNumber)
    End Sub
End Module
' The example displays the following output:
'       Original values of m1 and m2:
'          m1 instance values:
'             Name: Sam, Age: 42
'             Value: 6565
'          m2 instance values:
'             Name: Sam, Age: 42
'             Value: 6565
'       
'       Values of m1 and m2 after changes to m1:
'          m1 instance values:
'             Name: Frank, Age: 32
'             Value: 7878
'          m2 instance values:
'             Name: Sam, Age: 42
'             Value: 7878
'       
'       Values of m1 and m3 after changes to m1:
'          m1 instance values:
'             Name: George, Age: 39
'             Value: 8641
'          m3 instance values:
'             Name: Frank, Age: 32
'             Value: 7878

In dit voorbeeld retourneert de Person.IdInfo eigenschap een IdInfo object. Zoals in de uitvoer van het voorbeeld wordt weergegeven, is het gekloonde Person object, wanneer een Person object wordt gekloond door de MemberwiseClone methode aan te roepen, een onafhankelijke kopie van het oorspronkelijke object, behalve dat ze dezelfde Person.IdInfo objectverwijzing delen. Als u de eigenschap van Person.IdInfo de kloon wijzigt, wordt de eigenschap van Person.IdInfo het oorspronkelijke object gewijzigd. Wanneer een diepe kopieerbewerking wordt uitgevoerd, kan het gekloonde Person object, met inbegrip van Person.IdInfo de eigenschap, worden gewijzigd zonder dat dit van invloed is op het oorspronkelijke object.

Opmerkingen

De MemberwiseClone methode maakt een ondiepe kopie door een nieuw object te maken en vervolgens de niet-statische velden van het huidige object naar het nieuwe object te kopiëren. Als een veld een waardetype is, wordt een bit-by-bit-kopie van het veld uitgevoerd. Als een veld een verwijzingstype is, wordt de verwijzing gekopieerd, maar het object waarnaar wordt verwezen niet; Daarom verwijzen het oorspronkelijke object en de kloon ervan naar hetzelfde object.

Als u het verschil tussen een ondiepe en een diepe kopieerbewerking wilt illustreren, kunt u een object met de naam X overwegen dat verwijst naar objecten A en B. Object B verwijst op zijn beurt naar object C. Een ondiepe kopie van X maakt een nieuw object X2 dat ook verwijst naar objecten A en B. Een diepe kopie van X maakt daarentegen een nieuw object X2 dat verwijst naar de nieuwe objecten A2 en B2, die kopieën zijn van A en B. B2 verwijst op zijn beurt naar het nieuwe object C2, een kopie van C.

Er zijn talloze manieren om een grondige kopieerbewerking te implementeren als de ondiepe kopieerbewerking die door de MemberwiseClone methode wordt uitgevoerd, niet aan uw behoeften voldoet. Deze omvatten het volgende:

  • Roep een klasseconstructor aan van het object dat moet worden gekopieerd om een tweede object te maken met eigenschapswaarden die afkomstig zijn van het eerste object. Hierbij wordt ervan uitgegaan dat de waarden van een object volledig worden gedefinieerd door de klasseconstructor.
  • Roep de MemberwiseClone methode aan om een ondiepe kopie van een object te maken en wijs vervolgens nieuwe objecten toe waarvan de waarden hetzelfde zijn als het oorspronkelijke object aan eigenschappen of velden waarvan de waarden verwijzingstypen zijn. De DeepCopy methode in het voorbeeld illustreert deze benadering.
  • Serialiseer het object dat u diep wilt kopiëren en herstel vervolgens de geserialiseerde gegevens naar een andere objectvariabele.
  • Gebruik reflectie met recursie om de deep copy-bewerking uit te voeren.

Van toepassing op