Kopiowanie POCO

Kopiowanie obiektów mogło by się wydawać prostą sprawą, jednak powracając do podstaw języka przypomnimy sobie o referencjach.
Na początek przytocze bardzo fajny i pomocny artykuł Copying, Cloning, and Marshalling in .NET Powyższy artykuł wspomina o tworzeniu płytkiej oraz głębokiej kopi.
Aby wykonać płytką kopie nie trzeba wiele wysiłku ponieważ dostępna jest metoda MemberwiseClone
public virtual MyCloneableClass Clone()
{
    // płytka kopia klasy
    MyCloneableClass x =  this.MemberwiseClone() as MyCloneableClass;
}
Po zrobieniu płytkiej kopi obiektu możliwe jest oczywiście zrobienie kopi wszystkich obiektów będących propercjami obiektu kopiowanego w celu uzyskania głębokiego kopiowania.
Można znaleźć kolekcje - Listę w propercjach obiektu korzystając z reflection.
public void Funcky (BusinessObject c)
{
                var p = c.GetType().GetProperties();
                foreach (PropertyInfo pro in p)
                {
                    MethodInfo mi = pro.GetGetMethod();
                    ICollection collection = mi.Invoke(c, null) as ICollection;
                    if (collection != null)
                    {
                        IEnumerator iter = collection.GetEnumerator();
                        while (iter.MoveNext())
                        {
                            if (iter.Current is BusinessObject)
                            { 
                                //Do something smart
                                //np płytką kopie obiektu
                            }
                        }
                    }
                }
}
Innym wyjściem jest napisanie funkcji serializującej i deserializującej obiekt kopiowany. Pamiętajmy o oznaczeniu klasy jako serializowalna.
  [Serializable]
  public class MyCloneableClass {}

  public T DeepCopy< T >() 
  {
        MemoryStream memoryStream = new MemoryStream();
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(memoryStream, this);
        memoryStream.Seek(0, SeekOrigin.Begin);
        T objectCopy = (T)binaryFormatter.Deserialize(memoryStream);
        memoryStream.Close();
        return objectCopy;
  }
Z takim głębokim kopiowaniem należy ostrożnie postępować jeśli używamy jakichś obiektów które są leniwie ładowane ;)

Komentarze

Popularne posty