C# Object Cloner

I recently came across the need to replicate large numbers of objects, so I will share this nice piece of code. The following snippet is a class for deep cloning of objects (usually instances of classes) in C# posted by Stephen Inglish:

/// <summary>
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
///
/// 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);
        }
    }
}

The code essentially serializes the object and all serializable objects to which it contains references.  It then deserializes the result into a new reference, effectively cloning the entire object.  I have put together a basic example that uses this cloner.  First, a couple classes:

[Serializable]
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

[Serializable]
public class Group
{
    public List<Person> Members
    {
        get;
        private set;
    }

    public Group()
    {
        Members = new List<Person>();
    }
}

A group simply contains a list of people.  Note that these must be given the [Serializable] attribute to be cloned.  Then we can create a couple of groups and clone one:

// make some people
Person jack = new Person("Jack", 24);
Person bruce = new Person("Bruce", 22);
Person mary = new Person("Mary", 25);
Person jill = new Person("Jill", 23);

// create the boys
Group boys = new Group();
boys.Members.Add(jack);
boys.Members.Add(bruce);

// create the girls
Group girls = new Group();
girls.Members.Add(mary);
girls.Members.Add(jill);

// make a couple
Group dating = new Group();
dating.Members.Add(jack);
dating.Members.Add(jill);

// clone this couple
Group couple = ObjectCopier.Clone<Group>(dating);

// alter the original people dating
jack.Age = 100;
jill.Age = 100;

// check the clones' ages
foreach (Person person in couple.Members)
{
    Console.WriteLine(person.Name + " is " + person.Age);
}

This will first output Jack is 24 and then Jill is 23, demonstrating that the objects are cloned and retain their own copies of the objects the “parent” objects originally referenced.

This entry was posted in C# and tagged , , , . Bookmark the permalink.
  • Delicious
  • Facebook
  • Reddit
  • StumbleUpon
  • Twitter
  • RSS Feed
  • Google
  • Digg

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>