Click here to Skip to main content
Click here to Skip to main content

Implementing Deep Cloning via Serializing objects

By , 22 Feb 2008
 

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

  • 22nd February, 2008: Version 1.0: Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Stephen Inglish
Software Developer (Senior) Harland Financial Solutions
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionSerialization is very slow, use direct assigning.membercomaric31 Jan '13 - 3:31 
So I run small test to see, what is faster for deep copy. I made an object containing propertyes (filled), several list with several values in it. Some list had no item, some had one item and some, conataining another object, had about 5 items.
 
10 000 iterations showed, that it is much faster to do a deep copy of an object using simple assigning values.
 
I made two datetime values. One took Now() before 10 000 iterations and the second took Now() after 10 000 iterations. I run these 20 times for each metod and the result is clear. Average miliseconds for assigning method is 15,55. For serialization method it is 1263,4 miliseconds. The gap is so big, that I think I can say, that it is better to use assigning metod almost every time.
QuestionHow do I make a Type serializablememberAlexanderBlade10 Apr '12 - 12:08 
Hi I'm using Mvc3 and I'm a bit of a newbie to MVC3. I get the error message about the type needs to be serializable. How can I solve this? Is they any way around this?
 
Thanks for any help or suggestions.
AnswerRe: How do I make a Type serializablememberStephen Inglish10 Apr '12 - 12:25 
I don't know much about MVC, but if you add the Serializable attribute to most objects, that is sufficient to make an object binary serializable.
 
[Serializable]
public class MyClass
{
  public string MyProperty { get; set; }
}
 
If you wish to make an object XML serializable, than you may wish to consider using the DataContract and DataMember attributes.
 
[DataContract]
public class MyClass
{
  [DataMember]
  public string MyProperty { get; set; }
}
 

If you want to read a white paper on serialization, there is one here that is pretty decent.
Stephen Inglish
MCPD: Windows Developer
MCPD: Web Developer
MCPD: Enterprise Developer

GeneralRe: How do I make a Type serializablememberAlexanderBlade11 Apr '12 - 16:17 
Thanks for the help I got pass the serializing issue but I ran into another error. As I’m still a bit new to this I’m not sure that it’s the ObjectCloner or an MVC thing. I’m basically trying to clone the object before passing it to TryUpdateModel. Here’s the error message I get:
The object could not be added or attached because its EntityReference has an EntityKey property value that does not match the EntityKey for this object.
Here’s my action
 
[HttpPost]
public ActionResult Create(int id, FormCollection col)
{
 
var courseprogresses = db.CourseProgresses.Include(c => c.Course).Include(c => c.Teacher).Include (a=>a.Assignment).Include (s=>s.Student).Single(z=>z.CourseProgressId==id);

var cProgress = new CourseProgress();
cProgress= ObjectCopier.Clone(courseprogresses);
 
if (TryUpdateModel(cProgress))
{
db.CourseProgresses.Add(cProgress);
 
db.SaveChanges();
 
Any ideas?
QuestionAlternative method to copy object to reduce performance penaltymemberjozamm5 Aug '11 - 18:32 
Hi,
 
I am using this function to deep clone my objects, however for performance sensitive applications i am having a performance penalty that is about 10% of the execution time.
 
Can some please suggest to me another method of creating a copy of an object and having a smaller performance penalty?
 
Thanks,
 
Joseph
AnswerRe: Alternative method to copy object to reduce performance penaltymemberStephen Inglish6 Aug '11 - 4:23 
I've never checked the performance differences, but I would believe implementing IClonable on the objects you want to clone would be the most straightforward and efficient approach.
 
If you feel creative, you may be able to make a T4 template in visual studio or a CodeSmith project that implements IClonable on your objects, so you don't have to do it manually anytime you change your objects.
Stephen Inglish
Consultant
Sogeti USA
MCPD: Windows Developer
MCPD: Web Developer
MCPD: Enterprise Developer

GeneralFYImemberlagerdalek23 May '10 - 13:04 
I referenced your cloner at stackoverflow.com a while ago, to much acclaim and reputation. Thought I should do you the benefit of informing you.
 
http://stackoverflow.com/questions/78536/cloning-objects-in-c/78612#78612[^]
GeneralJust One Small Correction...memberno-paper20 Mar '09 - 6:17 
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 awarememberilya lozovyy29 Apr '08 - 9:33 
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^2memberTom Hawkins17 Apr '08 - 10:45 
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!!!memberWeslei Gomes24 Mar '08 - 11:15 
It's really a very good idea!!! Congratulations!
QuestionWhat about the performance penalty?memberAndyHo26 Feb '08 - 2:14 
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 Ideamembermerlin98125 Feb '08 - 4:27 
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 22 Feb 2008
Article Copyright 2008 by Stephen Inglish
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid