Een kopie van een object maken in C#

Kijk eens naar de onderstaande code (uittreksel uit een C# boek):

public class MyClass 
{
    public int val;
}
public struct myStruct 
{
    public int val;
}
public class Program 
{
    private static void Main(string[] args) 
    {
        MyClass objectA = new MyClass();
        MyClass objectB = objectA;

        objectA.val = 10;
        objectB.val = 20;

        myStruct structA = new myStruct();
        myStruct structB = structA;

        structA.val = 30;
        structB.val = 40;

        Console.WriteLine("objectA.val = {0}", objectA.val);
        Console.WriteLine("objectB.val = {0}", objectB.val);
        Console.WriteLine("structA.val = {0}", structA.val);
        Console.WriteLine("structB.val = {0}", structB.val);

        Console.ReadKey();
    }
}

Ik begrijp dat het de onderstaande uitvoer produceert:

objectA.val = 20
objectB.val = 20
structA.val = 30
structB.val = 40

De laatste twee regels van de uitvoer heb ik geen probleem mee, maar de eerste twee vertellen me dat objectA en objectB naar hetzelfde geheugenblok wijzen (omdat in C# objecten referentietypes zijn).

De vraag is hoe maak ik van objectB, een kopie van objectA, zodat het naar een ander gebied in het geheugen wijst. Ik begrijp dat het toewijzen van hun leden misschien niet werkt, omdat die leden ook referenties kunnen zijn. Dus hoe maak ik van objectB een compleet andere entiteit dan objectA?

Bedankt

Je zou het kunnen doen:

class myClass : ICloneable
{
    public String test;
    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

dan kun je doen

myClass a = new myClass();
myClass b = (myClass)a.Clone();

N.B. MemberwiseClone() Creëert een ondiepe kopie van het huidige System.Object.

Commentaren (6)
Oplossing

Er is geen ingebouwde manier. Je kunt MyClass de IClonable interface laten implementeren (maar die is min of meer deprecated) of gewoon je eigen Copy/Clone methode schrijven. In beide gevallen zul je wat code moeten schrijven.

Voor grote objecten kun je Serialisatie + Deserialisatie (via een MemoryStream) overwegen, gewoon om bestaande code te hergebruiken.

Welke methode je ook kiest, denk goed na over wat "a copy" precies betekent. Hoe diep moet het gaan, zijn er Id velden die uitgezonderd moeten worden etc.

Commentaren (6)

Er is hier al een vraag over, misschien kunt u die lezen

https://stackoverflow.com/questions/78536/cloning-objects-in-c

Er'is geen Clone() methode zoals die bijvoorbeeld in Java bestaat, maar je zou een kopie constructor in je clases kunnen opnemen, dat'is een andere goede aanpak.

class A
{
  private int attr

  public int Attr
  {
     get { return attr; }
     set { attr = value }
  }

  public A()
  {
  }

  public A(A p)
  {
     this.attr = p.Attr;
  }  
}

Dit zou een voorbeeld zijn, waarbij het lid 'Attr' wordt gekopieerd bij het bouwen van het nieuwe object.

Commentaren (0)