This project has moved. For the latest updates, please go here.

Deep Cloning

These are the topics you'll find covered on this page:

Introduction

The object class in .NET provides a static MemberwiseClone method that allows you to create a shallow copy of an object instance, but there is no corresponding facility for creating deep clones of objects (unless you want to resort to serialization). Fasterflect provides an extension method called DeepClone to fill this gap.

Cloning objects

The following shows the signature of the DeepClone extension method.

T DeepClone<T>( this T source );

The only requirement for using this method is that all reference types in the object graph to clone (the source parameter) have a default constructor. Without this requirement it would be difficult (and not necessarily always possible) for the method to recursively clone any reference objects encountered in the graph.

It's also worth mentioning that every unique object in the graph is cloned only once - any subsequent references to the same object will not result in a new copy being created. Instead, Fasterflect inserts a reference to the first clone created for the same reference. This ensures that the clone of the object graph contains exactly the same amount of unique object references as the original object graph. This also means that DeepClone handles cyclic references in the object graph, so you avoid both endless loops and duplicate clones.

This calls for a quick example.

// here's a classic example of a class that could be used to create an object graph with cyclic references:
public class Employee 
{
    public string Name { get; private set; }
    public Employee Manager { get; set; }

    // we need a default constructor for DeepClone to work
    public Employee() {}
    // observe that passing in null for the manager will make this employee his/her own manager
    public Employee( string name, Employee manager ) { Name = name; Manager = manager ?? this; }
}

// now lets create an example object for testing the DeepClone method
var employee = new Employee( "Ford Prefect", null );
var clone = employee.DeepClone();

// let's verify that the graph has been cloned correctly
Assert.AreNotSame( employee, clone );
Assert.AreEqual( employee.Name, clone.Name );
Assert.AreNotSame( employee.Manager, clone.Manager );
Assert.AreSame( clone, clone.Manager );

Links

  • Services Returns you to the advanced Fasterflect features index page
  • Documenation Returns you to the documentation index page

Last edited Mar 21, 2010 at 7:36 AM by buunguyen, version 6

Comments

Vin55 Jan 19, 2013 at 3:25 PM 
Is there a way to limit the depth of clone at least for some references? I have an object graph to clone which in turn have references pointing back to the object in which I start the cloning operation, and I don't want to have another instance of that object. A bit more complicated case is to clone only a well-defined component of the graph, can one have such fine control? I've already implemeted part of the described functionality, but it'd be great to know if I can use this simple general solution of yours!

buunguyen Aug 13, 2012 at 9:07 PM 
@keft: sorry for taking long to response, we're not aware of this comment until now. Fasterflect only makes sense if you are to perform some operation many many times. If you just do it a few times during the application life cycle, reflection should be used instead. The reason is because the first time an operation is performed, Fasterflect has to generate CIL and stuff, which is costly operation while being beneficial for subsequent calls.

keft Nov 22, 2011 at 8:29 AM 
When I tried this on a small object it took almost 5 times more time than regular serialization. Am I doing something wrong?