martes, 25 de mayo de 2010

Como clonar objetos con c#

hace unos dias, me toco tener que clonar una instancia de un objeto. hasta ahora solo lo hacia creando un nuevo objeto y pasando los valores.

bueno encontre una forma mejor de hacerlo, y lo mejor que con menos posibilidades de errores. ya que como lo hacie antes probablemente me falte copiar algun valor.

Supongamos que tenemos la tipica clase persona:


public class persona{
public virtual string Nombres{get;set;}
public virtual string Apellidos{get;set;}
public virtual Direccion Direccion{get;set;}
public string NombreCompuesto{
return string.Format("{0} {1} ", Nombres, Apellidos);
}
}


y necesitamos clonarla, simplemente decimos que implementa ICloneable, y agregamos el metodo clone, en este motodo llamamos al metodo MemberwiseClone. de la siguiente manera

public class persona : ICloneable{
public virtual string Nombres{get;set;}
public virtual string Apellidos{get;set;}
public virtual Direccion Direccion{get;set;}
public string NombreCompuesto{
return string.Format("{0} {1} ", Nombres, Apellidos);
}

object Clone() {
return MemberwiseClone(); ;
}
}










--
Atte.
Victor Hugo Saavedra
http://vhspiceros.blogspot.com

7 comentarios:

  1. Muy buena explicacion, quedo excelente.....

    ResponderEliminar
  2. Te copio la definición de msdn.
    Es muy importante no fiarse mucho de este método. O por lo menos saber bien que es lo que hace si no se quieren futuras sorpresas.

    El método MemberwiseClone crea una copia superficial mediante la creación de un nuevo objeto y la copia posterior de los campos no estáticos del objeto actual en el objeto nuevo. Si un campo es de un tipo de valor, se realiza una copia bit a bit de él. Si un campo es un tipo de referencia, se copia la referencia pero no el objeto al que se hace referencia; por consiguiente, el objeto original y su copia hacen referencia al mismo objeto.

    Por ejemplo, considere un objeto denominado X que hace referencia a los objetos A y B. El objeto B, a su vez, hace referencia al objeto C. Una copia superficial de X crea un nuevo objeto X2 que también hace referencia a los objetos A y B. En cambio, una copia en profundidad de X crea un nuevo objeto X2 que hace referencia a los nuevos objetos A2 y B2, que son copias de A y B. B2, a su vez, hace referencia al nuevo objeto C2, que es una copia de C.

    Busca algo de serialización binaria para la copia en profundidad.

    Algo así:

    public Object CloneBinary()
    {
    return FromBinary(ToBinary());
    }
    public Byte[] ToBinary()
    {
    // Serialize this. --> ToArray
    }
    public Object FromBinary(Byte[] buffer)

    Saludos desde España.

    RSO

    ResponderEliminar
  3. Tienes toda la razón amigo español, ¿¡no hay un método mas sencillo!?

    Si quieren probar allí hay Código

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace CursoNet
    {
    class Program
    {
    static void Main(string[] args)
    {

    int x = 10;
    int y = x;

    x = 20;

    Console.WriteLine(x);
    Console.WriteLine(y);

    Entero z = new Entero(10);
    Entero w = z;//¿Qué ocurre aquí?
    Entero r = (Entero)z.Clone();
    z.numEntero = 20;
    z.prueba.t = 25;

    Console.WriteLine(z.prueba.t);
    Console.WriteLine(r.prueba.t);//NO DEBERÍA VALER 25


    Console.WriteLine(z.numEntero);
    Console.WriteLine(w.numEntero);//¿El valor de w es 10?
    Console.WriteLine(r.numEntero);

    Console.ReadLine();

    }

    class Entero: ICloneable
    {
    public int numEntero;

    public Entero(int x)
    {
    numEntero = x;

    }

    public object Clone()
    {
    return (Entero)MemberwiseClone();
    }

    public OtroNumero prueba = new OtroNumero();

    }

    class OtroNumero
    {
    public int t;
    }
    }
    }

    ResponderEliminar
  4. Muy buen aporte. Y la explicación sobre qué es lo que hace sobre tipos referencia. Buenos aclaración, precisamente para no llevarnos posteriores sorpresas.

    ResponderEliminar
  5. http://stackoverflow.com/questions/78536/deep-cloning-objects-in-c-sharp

    ResponderEliminar