Cloning objects in .NET

In an interesting project where I'm giving a hand, we need to clone objects of a number of different types, perhaps surprisingly the CLR doesn't offer a general cloning method, of course you could use MemberwiseClone() but this is a protected method, so it can be invoked only from inside the class of the object being cloned, which makes it difficult to use it in a general method, besides, MemberWiseClone() does just a shallow copy and what we really need is a deep copy.

There is a good reason for not having such a general method: object cloning is one of those problems which have a simple solution for simple scenarios but that resist a satisfactory solution for all the scenarios, for example the objects may have references to other objects and even to themselves be it directly or after a long chain, for example a customer has invoices that have payments that refer to the customer, a general cloning algorithm for a web several times more complex than that is anything but trivial. But the need of moving objects (and their web) is inescapable in distributed environments, because you have to move the invoices and the customers from the business layer to the presentation layer, so there are indeed mechanisms, albeit with some limitations, for serializing and deserializing object graphs, with the help of these mechanisms we can try and build a general object cloner:

    1 

    2     public static T BinaryClone<T>(this T originalObject)

    3     {

    4         using (var stream = new System.IO.MemoryStream())

    5         {

    6             var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

    7             binaryFormatter.Serialize(stream, originalObject);

    8             stream.Position = 0;

    9             return (T)binaryFormatter.Deserialize(stream);

   10         }

   11     }

   12 

We just convert, using as intermediary a memory stream, our object to a bit string and then we synthesize a *new object* from that bit string. The use of BinaryClone() flows nicely:

    1 

    2     var clone = person.BinaryClone();

    3 

Easy to write, but we have to be careful of the performance and the corner cases. I run a few *very informal* performance tests with this object:

    1 

    2     var person = new Person

    3     {

    4         Id = 101,

    5         Name = "Sánchez, Sebastián",

    6         Salary = 590.20m,

    7         BirthDate = new DateTime(2000, 6, 15),

    8         Address = new Address { Number = "N24-78", Street = "Pasaje Córdova" }

    9     };

   10 

And I found that doing a hundred thousand clones takes some nine thousand milliseconds, that is each cloning takes less than one ten-thousandth of a second, which is adequate to our needs. BinaryFormatter has been with us since .NET Framework 1.0 so I'm not like saying anything even remotely new or unknown, but tomorrow (or the day after, or the day after...) I'll talk about a small refinement to BinaryClone().

Published Sunday, May 18, 2008 1:27 AM by Edgar Sánchez
Filed under: ,

Comments

# re: Cloning objects in .NET

Sunday, May 18, 2008 1:56 PM by flalar

read this: andersnoras.com/.../icloneable-revisited.aspx

and this:

andersnoras.com/.../blazing-fast-reflection.aspx

# re: Cloning objects in .NET

Thursday, June 05, 2008 5:38 PM by Oskar Austegard

We actually had to do something like this for a project running VB.NET 1.1 Mobile Framework, back in 2004, and we did basically the same thing.  I'm both a bit excited and a bit sad to see the same solution in C# 2.0/3.0 four years later...

# re: Cloning objects in .NET

Thursday, January 28, 2010 2:05 PM by theluk

^the problem is, that object must be serializable. If you inherit from controls, you cannot change attributes like the serializable one, you got a new problem

Leave a Comment

(required) 
(required) 
(optional)
(required)