none
Deep Copying Objects RRS feed

  • Question

  • I'm trying to deep copy a user defined object i.e. copy the actual data and not the references. The object is slightly complex as it has other user-defined data structures. The structre is something like:

    public class MainObject : BaseClass
    {
       protected TypeA a;
       protected TypeB b;
       protected List<TypeC> listOfC;
       ...etc
    }

    The idea is to use binary serialization but I don't want to mark the derived and base class of every object type as [Serializable] (TypeA and TypeB are in turn derived classes or base classes to other classes). This would make almost all the classes in the application Serializable!

    I was surprised to not see much help on this matter on the forums which led me to believe that I'm missing something in this picture. Is there a simpler way to achieve this?

    Thanks.

    Tuesday, March 31, 2009 5:05 PM

Answers

  • Deep copying isn't support in the framework.  .NET supports shallow copying only.  In order to get it to work each object you want to copy has to support it.  Serialization is one way to achieve this and is perhaps the easiest.  If an object doesn't support serialization (or more correctly deserialization) then you aren't going to be able to support deep copy.  The problem is that without intimate knowledge of the object there is no way for you to know if all the internal objects have been saved/restored.  You might be able to use reflection but I can't imagine it would be easy.

    You could consider implementing the ICloneable interface instead.  All your objects would have to implement it but it would allow you to use deep cloning.  This interface was introduced in v1.x but is not heavily used because it doesn't distinguish between shallow and deep copies.

    Michael Taylor - 3/31/09
    http://p3net.mvps.org
    Tuesday, March 31, 2009 9:21 PM
    Moderator

All replies

  • Deep copying isn't support in the framework.  .NET supports shallow copying only.  In order to get it to work each object you want to copy has to support it.  Serialization is one way to achieve this and is perhaps the easiest.  If an object doesn't support serialization (or more correctly deserialization) then you aren't going to be able to support deep copy.  The problem is that without intimate knowledge of the object there is no way for you to know if all the internal objects have been saved/restored.  You might be able to use reflection but I can't imagine it would be easy.

    You could consider implementing the ICloneable interface instead.  All your objects would have to implement it but it would allow you to use deep cloning.  This interface was introduced in v1.x but is not heavily used because it doesn't distinguish between shallow and deep copies.

    Michael Taylor - 3/31/09
    http://p3net.mvps.org
    Tuesday, March 31, 2009 9:21 PM
    Moderator
  • For deep copying I use the following structure, which is not 100% guaranteed but works for me:
    A FullCopy method, that:
    1 - If the object is ICloneable, calls clone.
    2 - If the object is not ICloneable, does a MemberwiseClone() and then, using reflection, does a Clone() on each ICloneable field it has.

    Of course, there are limitations. You may want to serialize any reference type that is not ICloneable to guarantee you are not pointing to the same reference. For me that was unnecessary, as such FullClone() method is available from a certain object, which I myself guarantee inheritors to follow the pattern.


    Paulo Zemek - System Architect
    Friday, April 3, 2009 2:13 AM
  • Thanks Michael and Paulo!
    Monday, April 6, 2009 4:41 PM