Skip to content

Deep Cloning

Ricardo Diaz edited this page Aug 7, 2017 · 1 revision

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 );
Clone this wiki locally