Click here to Skip to main content
Email Password   helpLost your password?

Introduction

I was looking around on The Code Project and saw an article talking about the different implementation styles for deep cloning an object. The article referred to an article using Reflection for Deep Cloning an object, but had no article to reference for using Serialization.

Using the Code

This is a helper class that can be used to perform a deep copy of an object:

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;     
      
/// <summary>
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
public static class ObjectCopier
{
 /// <summary>
 /// Perform a deep Copy of the object.
 /// </summary>
 /// <typeparam name="T">The type of object being copied.</typeparam>
 /// <param name="source">The object instance to copy.</param>
 /// <returns>The copied object.</returns>
 public static T Clone<T>(T source)
 {
  if (!typeof(T).IsSerializable)
  {
    throw new ArgumentException("The type must be serializable.", "source");
  }
  
  // Don't serialize a null object, simply return the default for that object
  if (Object.ReferenceEquals(source, null))
  {
    return default(T);
  }

  IFormatter formatter = new BinaryFormatter();
  Stream stream = new MemoryStream();
  using (stream)
  {
    formatter.Serialize(stream, source);
    stream.Seek(0, SeekOrigin.Begin);
    return (T)formatter.Deserialize(stream);
  }
 }
}

Usage of this class becomes ObjectCopier.Clone(objectBeingCloned);.

Points of Interest

In case you prefer to use the new Extension methods of C# 3.0, change the method to have the following signature:

   public static T Clone<T>(this T source)
   {
      ...
   }

Now the method call simply becomes objectBeingCloned.Clone();.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralJust One Small Correction...
no-paper
7:17 20 Mar '09  
If the type of the source object is a subclass of T that is not serializable, the code will be tricked into attempting to serialize it (which of course will fail).
Changing the line
   if (!typeof(T).IsSerializable)
to
   if (!source.GetType().IsSerializable)
seems to resolve this issue for me.

Cheers
GeneralGood use of generics but be aware
ilya lozovyy
10:33 29 Apr '08  
Good use of generics however you also have to know that this is not true deep cloning
because not all of the properties of the objects might be cloned. A good example
of that is if you have a property on the class that you are cloning and that property references
another object that is not clonable then that object is not cloned and thus making
this solution not a deep copy.

After all is said and done, usually more is said than done.

GeneralE=MC^2
Tom Hawkins
11:45 17 Apr '08  
So, DeepCloning(someobject) = Deserialize(Serialize(someobject))

And regarding one comment where someone brought up performance, well, I would suggest that if you can come up with a performant serialization strategy deep cloning comes along for the ride.

Very cool,
Tom
GeneralExcellent idea!!!
Weslei Gomes
12:15 24 Mar '08  
It's really a very good idea!!! Congratulations!
GeneralWhat about the performance penalty?
AndyHo
3:14 26 Feb '08  
In my experience the serialization has a tremendous performance penalty. Even more than reflection.
And in the other hand the class MUST be flagged as serializable, which dont allow many type of objects living inside. Wink

- Andy -
see some magic at: www.pandorabox.com.ar
GeneralVery Interesting Idea
merlin981
5:27 25 Feb '08  
This is an excellent idea for cloning.

Keep in mind, though, that some complex objects (such as dictionaries) are not serializable. You will need to override the serialize and deserialize functions to handle those objects.



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rhabot - World of Warcraft Bot
Uber RPGE - Free Private World of Warcraft Server
Make long URLs short with NeatURL.net
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Last Updated 22 Feb 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010