Creación de una copia de un objeto en C#

Por favor, echa un vistazo al código de abajo (extracto de un libro de C#):

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();
    }
}

Entiendo que produce la salida de abajo:

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

Las dos últimas líneas de la salida no me suponen ningún problema, pero las dos primeras me indican que objetoA y objetoB están apuntando al mismo bloque de memoria (ya que en C# los objetos son de tipo referencia).

La pregunta es cómo hacer que objetoB, sea una copia de objetoA para que apunte a una zona diferente de la memoria. Entiendo que intentar asignar sus miembros puede no funcionar ya que esos miembros pueden ser referencias también. Entonces, ¿cómo hago para que el objetoB sea una entidad completamente diferente del objetoA?

Gracias

Podrías hacerlo:

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

entonces puedes hacer

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

N.B. MemberwiseClone() Crea una copia superficial del actual System.Object.

Comentarios (6)
Solución

No hay una forma incorporada. Puedes hacer que MyClass implemente la interfaz IClonable (pero está algo obsoleta) o simplemente escribir tu propio método Copy/Clone. En cualquier caso tendrás que escribir algo de código.

Para objetos grandes podrías considerar la Serialización + Deserialización (a través de un MemoryStream), sólo para reutilizar el código existente.

Cualquiera que sea el método, piense cuidadosamente sobre lo que "una copia" significa exactamente. Hasta dónde debe llegar, si hay campos Id que deben ser exceptuados, etc.

Comentarios (6)

Ya hay una pregunta sobre esto, tal vez pueda leerla

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

No hay un método Clone() como el que existe en Java por ejemplo, pero podrías incluir un constructor de copia en tus clases, ese'es otro buen enfoque.

class A
{
  private int attr

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

  public A()
  {
  }

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

Este sería un ejemplo, copiando el miembro 'Attr' al construir el nuevo objeto.

Comentarios (0)