21 de mayo de 2010

Clonar Objeto con C#

C# Clonar un objeto complejo: Veamos un ejemplo práctico y sencillo de como clonar o duplicar un objeto de estructura compleja.

La mayoría de los datos que solemos utilizar en nuestras aplicaciones, son tipos de datos por referencia, lo que implica que cuando igualamos una variable a otra (objeto1 = objeto2;) en realidad estamos definiendo que objeto1 apunte a la misma dirección de memoria que objeto2; de tal manera que si cambiamos una propiedad en el objeto1, esta cambiará también para el objeto2 (y viceversa).

Pero existen determinados escenarios donde necesitamos hacer una copia duplicada del objeto (clonación). Para lograrlo tenemos en .NET a nuestra disposición varias técnicas, con sus propias ventajas y desventajas. En este post pretendo comentar como lograr la clonación de la forma más sencilla (bajo mi punto de vista) aunque debo advertirte que no es la más eficiente en cuanto a consumo de recursos, pero sí la más ágil y fácil de mantener.

Posibles técnicas de clonación:

  1. Serialización y Deserialización del objeto.
  2. Implementar la interfaz IClonable para la clase.
  3. Usar MemberwiseClone() con Reflection.

Nota: De momento no se me ocurre ninguna otra técnica de clonación de objetos en .NET, si conoces alguna escríbeme un comentario para incluirla.

 

Clonar un Objeto con Serialización y Deserialización

Esta técnica de clonación de objetos .Net, consiste en:

  • Tomar el objeto que queremos clonar o duplicar, y serializarlo.
  • Tomar el resultado de la serialización y deserializarlo.
  • Almacenar la deserialización en la nueva variable.

Pero vallamos a la practica, veamos un ejemplo de como lograrlo:

//Creo el objeto de tipo Contacto
Contacto objeto1 = new Contacto { Id = 1, Nombre = "Pedro", Tel = "601010101" };
 
//Serializar objeto1 a XML
string xmlContacto = objeto1.SerializarToXml();
 
//Deserializar XML a objClonado
Contacto objClonado = xmlContacto.DeserializarTo<Contacto>();

Nota: En el código anterior hemos usado 2 métodos extensores que explicaré más adelante en este mismo artículo (SerializarToXml - DeserializarTo<T>). La clase del ejemplo (Contacto) es muy simple y es mucho mejor cualquiera de las otras 2 técnicas mencionadas, pero igual nos sirve de base para mostrar la técnica de clonación con serialización y deserialización.

Y con esto ya tenemos clonado el objeto1; a partir de este momento ya tenemos 2 variables independientes (objeto1, objClonado); actualmente ambas tienen la misma información, pero al modificar una variable no cambiará la otra automáticamente. El código lo puse en tres líneas para una mejor comprensión, también podríamos haberlo hecho así:

Contacto objeto1 = new Contacto { Id = 1, Nombre = "Pedro", Tel = "601010101" };
Contacto objClonado = objeto1.SerializarToXml().DeserializarTo<Contacto>();

 

Métodos Extensores para serialización y deserialización XML

Solo me limitaré a dejar el código de ambos métodos extensores, pues con anterioridad ya escribí un artículo donde los comentaba en profundidad Serializar y Deserializar un objeto con C#.

//Serializar a XML (UTF-16) un objeto cualquiera
public static string SerializarToXml(this object obj)
{
  try
  {
    StringWriter strWriter = new StringWriter();
    XmlSerializer serializer = new XmlSerializer(obj.GetType());
 
    serializer.Serialize(strWriter, obj);
    string resultXml = strWriter.ToString();
    strWriter.Close();
 
    return resultXml;
  }
  catch
  {
      return string.Empty;
  }
}
 
//Deserializar un XML a un objeto T
public static T DeserializarTo<T>(this string xmlSerializado)
{
  try
  {
    XmlSerializer xmlSerz = new XmlSerializer(typeof(T));
 
    using (StringReader strReader = new StringReader(xmlSerializado))
    {
        object obj = xmlSerz.Deserialize(strReader);
        return (T)obj;
    }
  }
  catch { return default(T); }
}

Y hasta aquí el post…

 

Artículos Relacionados:

No hay comentarios:

Publicar un comentario