How to deep copy a class without marking it as Serializable

Gaddigesh picture Gaddigesh · Mar 30, 2010 · Viewed 23.5k times · Source

Given the following class:

class A
{
    public List<B> ListB;

    // etc...
}

where B is another class that may inherit/contain some other classes.


Given this scenario:

  1. A is a large class and contains many reference types
  2. I cannot mark B as [Serializable] as I don't have access to source code of B

The following methods to perform deep copying do not work:

  1. I cannot use ICloneable or MemberwiseClone as class A contains many reference types
  2. I cannot write a copy constructor for A, as the class is large and continuously being added to, and contains classes (like B) that cannot be deep copied
  3. I cannot use serialization as I cannot mark a contained class (like B, where no source code available) as [Serializable]

How can I deep copy class A?

Answer

Stefan Steinegger picture Stefan Steinegger · Mar 30, 2010

I stopped using serialization for deep copying anyway, because there is not enough control (not every class needs to be copied the same way). Then I started to implement my own deep copy interfaces and copy every property in the way it should be copied.

Typical ways to copy a referenced type:

  • use copy constructor
  • use factory method (eg. immutable types)
  • use your own "Clone"
  • copy only reference (eg. other Root-Type)
  • create new instance and copy properties (eg. types not written by yourself lacking a copy constructor)

Example:

class A
{
  // copy constructor
  public A(A copy) {}
}

// a referenced class implementing 
class B : IDeepCopy
{
  object Copy() { return new B(); }
}

class C : IDeepCopy
{
  A A;
  B B;
  object Copy()
  {
    C copy = new C();

    // copy property by property in a appropriate way
    copy.A = new A(this.A);
    copy.B = this.B.Copy();
  }
}

You may think that this a huge amount of work. But at the end, it is easy and straight forward, can be tuned where needed and does exactly what you need.