2399
votes

I want to do something like:

MyObject myObj = GetMyObj(); // Create and fill a new object
MyObject newObj = myObj.Clone();

And then make changes to the new object that are not reflected in the original object.

I don't often need this functionality, so when it's been necessary, I've resorted to creating a new object and then copying each property individually, but it always leaves me with the feeling that there is a better or more elegant way of handling the situation.

How can I clone or deep copy an object so that the cloned object can be modified without any changes being reflected in the original object?

30
May be useful: "Why Copying an Object is a terrible thing to do?" agiledeveloper.com/articles/cloning072002.htmPedro77
You should have a look at AutoMapperDaniel Little
Your solution is far more complex, I got lost reading it... hehehe. I'm using an DeepClone interface. public interface IDeepCloneable<T> { T DeepClone(); }Pedro77
@Pedro77 -- Though, interestingly, that article ends up saying to create a clone method on the class, then have it call an internal, private constructor that gets passed this. So copying is turrible [sic], but copying carefully (and the article's definitely worth reading) isn't. ;^)ruffin

30 Answers

1812
votes

Whereas one approach is to implement the ICloneable interface (described here, so I won't regurgitate), here's a nice deep clone object copier I found on The Code Project a while ago and incorporated it into our code. As mentioned elsewhere, it requires your objects to be serializable.

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

/// <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 via serialization.
    /// </summary>
    /// <typeparam name="T">The type of object being copied.</typeparam>
    /// <param name="source">The object instance to copy.</param>
    /// <returns>A deep copy of the object.</returns>
    public static T Clone<T>(T source)
    {
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", nameof(source));
        }

        // Don't serialize a null object, simply return the default for that object
        if (ReferenceEquals(self, null)) return default;

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

The idea is that it serializes your object and then deserializes it into a fresh object. The benefit is that you don't have to concern yourself about cloning everything when an object gets too complex.

In case of 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();.

EDIT (January 10 2015) Thought I'd revisit this, to mention I recently started using (Newtonsoft) Json to do this, it should be lighter, and avoids the overhead of [Serializable] tags. (NB @atconway has pointed out in the comments that private members are not cloned using the JSON method)

/// <summary>
/// Perform a deep Copy of the object, using Json as a serialization method. NOTE: Private members are not cloned using this method.
/// </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 CloneJson<T>(this T source)
{            
    // Don't serialize a null object, simply return the default for that object
    if (ReferenceEquals(self, null)) return default;

    // initialize inner objects individually
    // for example in default constructor some list property initialized with some values,
    // but in 'source' these items are cleaned -
    // without ObjectCreationHandling.Replace default constructor values will be added to result
    var deserializeSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace};

    return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
}
349
votes

I wanted a cloner for very simple objects of mostly primitives and lists. If your object is out of the box JSON serializable then this method will do the trick. This requires no modification or implementation of interfaces on the cloned class, just a JSON serializer like JSON.NET.

public static T Clone<T>(T source)
{
    var serialized = JsonConvert.SerializeObject(source);
    return JsonConvert.DeserializeObject<T>(serialized);
}

Also, you can use this extension method

public static class SystemExtension
{
    public static T Clone<T>(this T source)
    {
        var serialized = JsonConvert.SerializeObject(source);
        return JsonConvert.DeserializeObject<T>(serialized);
    }
}
185
votes

The reason not to use ICloneable is not because it doesn't have a generic interface. The reason not to use it is because it's vague. It doesn't make clear whether you're getting a shallow or a deep copy; that's up to the implementer.

Yes, MemberwiseClone makes a shallow copy, but the opposite of MemberwiseClone isn't Clone; it would be, perhaps, DeepClone, which doesn't exist. When you use an object through its ICloneable interface, you can't know which kind of cloning the underlying object performs. (And XML comments won't make it clear, because you'll get the interface comments rather than the ones on the object's Clone method.)

What I usually do is simply make a Copy method that does exactly what I want.

137
votes

After much much reading about many of the options linked here, and possible solutions for this issue, I believe all the options are summarized pretty well at Ian P's link (all other options are variations of those) and the best solution is provided by Pedro77's link on the question comments.

So I'll just copy relevant parts of those 2 references here. That way we can have:

The best thing to do for cloning objects in C sharp!

First and foremost, those are all our options:

The article Fast Deep Copy by Expression Trees has also performance comparison of cloning by Serialization, Reflection and Expression Trees.

Why I choose ICloneable (i.e. manually)

Mr Venkat Subramaniam (redundant link here) explains in much detail why.

All his article circles around an example that tries to be applicable for most cases, using 3 objects: Person, Brain and City. We want to clone a person, which will have its own brain but the same city. You can either picture all problems any of the other methods above can bring or read the article.

This is my slightly modified version of his conclusion:

Copying an object by specifying New followed by the class name often leads to code that is not extensible. Using clone, the application of prototype pattern, is a better way to achieve this. However, using clone as it is provided in C# (and Java) can be quite problematic as well. It is better to provide a protected (non-public) copy constructor and invoke that from the clone method. This gives us the ability to delegate the task of creating an object to an instance of a class itself, thus providing extensibility and also, safely creating the objects using the protected copy constructor.

Hopefully this implementation can make things clear:

public class Person : ICloneable
{
    private final Brain brain; // brain is final since I do not want 
                // any transplant on it once created!
    private int age;
    public Person(Brain aBrain, int theAge)
    {
        brain = aBrain; 
        age = theAge;
    }
    protected Person(Person another)
    {
        Brain refBrain = null;
        try
        {
            refBrain = (Brain) another.brain.clone();
            // You can set the brain in the constructor
        }
        catch(CloneNotSupportedException e) {}
        brain = refBrain;
        age = another.age;
    }
    public String toString()
    {
        return "This is person with " + brain;
        // Not meant to sound rude as it reads!
    }
    public Object clone()
    {
        return new Person(this);
    }
    …
}

Now consider having a class derive from Person.

public class SkilledPerson extends Person
{
    private String theSkills;
    public SkilledPerson(Brain aBrain, int theAge, String skills)
    {
        super(aBrain, theAge);
        theSkills = skills;
    }
    protected SkilledPerson(SkilledPerson another)
    {
        super(another);
        theSkills = another.theSkills;
    }

    public Object clone()
    {
        return new SkilledPerson(this);
    }
    public String toString()
    {
        return "SkilledPerson: " + super.toString();
    }
}

You may try running the following code:

public class User
{
    public static void play(Person p)
    {
        Person another = (Person) p.clone();
        System.out.println(p);
        System.out.println(another);
    }
    public static void main(String[] args)
    {
        Person sam = new Person(new Brain(), 1);
        play(sam);
        SkilledPerson bob = new SkilledPerson(new SmarterBrain(), 1, "Writer");
        play(bob);
    }
}

The output produced will be:

This is person with Brain@1fcc69
This is person with Brain@253498
SkilledPerson: This is person with SmarterBrain@1fef6f
SkilledPerson: This is person with SmarterBrain@209f4e

Observe that, if we keep a count of the number of objects, the clone as implemented here will keep a correct count of the number of objects.

90
votes

I prefer a copy constructor to a clone. The intent is clearer.

44
votes

Simple extension method to copy all the public properties. Works for any objects and does not require class to be [Serializable]. Can be extended for other access level.

public static void CopyTo( this object S, object T )
{
    foreach( var pS in S.GetType().GetProperties() )
    {
        foreach( var pT in T.GetType().GetProperties() )
        {
            if( pT.Name != pS.Name ) continue;
            ( pT.GetSetMethod() ).Invoke( T, new object[] 
            { pS.GetGetMethod().Invoke( S, null ) } );
        }
    };
}
35
votes

I've just created CloneExtensions library project. It performs fast, deep clone using simple assignment operations generated by Expression Tree runtime code compilation.

How to use it?

Instead of writing your own Clone or Copy methods with a tone of assignments between fields and properties make the program do it for yourself, using Expression Tree. GetClone<T>() method marked as extension method allows you to simply call it on your instance:

var newInstance = source.GetClone();

You can choose what should be copied from source to newInstance using CloningFlags enum:

var newInstance 
    = source.GetClone(CloningFlags.Properties | CloningFlags.CollectionItems);

What can be cloned?

  • Primitive (int, uint, byte, double, char, etc.), known immutable types (DateTime, TimeSpan, String) and delegates (including Action, Func, etc)
  • Nullable
  • T[] arrays
  • Custom classes and structs, including generic classes and structs.

Following class/struct members are cloned internally:

  • Values of public, not readonly fields
  • Values of public properties with both get and set accessors
  • Collection items for types implementing ICollection

How fast it is?

The solution is faster then reflection, because members information has to be gathered only once, before GetClone<T> is used for the first time for given type T.

It's also faster than serialization-based solution when you clone more then couple instances of the same type T.

and more...

Read more about generated expressions on documentation.

Sample expression debug listing for List<int>:

.Lambda #Lambda1<System.Func`4[System.Collections.Generic.List`1[System.Int32],CloneExtensions.CloningFlags,System.Collections.Generic.IDictionary`2[System.Type,System.Func`2[System.Object,System.Object]],System.Collections.Generic.List`1[System.Int32]]>(
    System.Collections.Generic.List`1[System.Int32] $source,
    CloneExtensions.CloningFlags $flags,
    System.Collections.Generic.IDictionary`2[System.Type,System.Func`2[System.Object,System.Object]] $initializers) {
    .Block(System.Collections.Generic.List`1[System.Int32] $target) {
        .If ($source == null) {
            .Return #Label1 { null }
        } .Else {
            .Default(System.Void)
        };
        .If (
            .Call $initializers.ContainsKey(.Constant<System.Type>(System.Collections.Generic.List`1[System.Int32]))
        ) {
            $target = (System.Collections.Generic.List`1[System.Int32]).Call ($initializers.Item[.Constant<System.Type>(System.Collections.Generic.List`1[System.Int32])]
            ).Invoke((System.Object)$source)
        } .Else {
            $target = .New System.Collections.Generic.List`1[System.Int32]()
        };
        .If (
            ((System.Byte)$flags & (System.Byte).Constant<CloneExtensions.CloningFlags>(Fields)) == (System.Byte).Constant<CloneExtensions.CloningFlags>(Fields)
        ) {
            .Default(System.Void)
        } .Else {
            .Default(System.Void)
        };
        .If (
            ((System.Byte)$flags & (System.Byte).Constant<CloneExtensions.CloningFlags>(Properties)) == (System.Byte).Constant<CloneExtensions.CloningFlags>(Properties)
        ) {
            .Block() {
                $target.Capacity = .Call CloneExtensions.CloneFactory.GetClone(
                    $source.Capacity,
                    $flags,
                    $initializers)
            }
        } .Else {
            .Default(System.Void)
        };
        .If (
            ((System.Byte)$flags & (System.Byte).Constant<CloneExtensions.CloningFlags>(CollectionItems)) == (System.Byte).Constant<CloneExtensions.CloningFlags>(CollectionItems)
        ) {
            .Block(
                System.Collections.Generic.IEnumerator`1[System.Int32] $var1,
                System.Collections.Generic.ICollection`1[System.Int32] $var2) {
                $var1 = (System.Collections.Generic.IEnumerator`1[System.Int32]).Call $source.GetEnumerator();
                $var2 = (System.Collections.Generic.ICollection`1[System.Int32])$target;
                .Loop  {
                    .If (.Call $var1.MoveNext() != False) {
                        .Call $var2.Add(.Call CloneExtensions.CloneFactory.GetClone(
                                $var1.Current,
                                $flags,


                         $initializers))
                } .Else {
                    .Break #Label2 { }
                }
            }
            .LabelTarget #Label2:
        }
    } .Else {
        .Default(System.Void)
    };
    .Label
        $target
    .LabelTarget #Label1:
}

}

what has the same meaning like following c# code:

(source, flags, initializers) =>
{
    if(source == null)
        return null;

    if(initializers.ContainsKey(typeof(List<int>))
        target = (List<int>)initializers[typeof(List<int>)].Invoke((object)source);
    else
        target = new List<int>();

    if((flags & CloningFlags.Properties) == CloningFlags.Properties)
    {
        target.Capacity = target.Capacity.GetClone(flags, initializers);
    }

    if((flags & CloningFlags.CollectionItems) == CloningFlags.CollectionItems)
    {
        var targetCollection = (ICollection<int>)target;
        foreach(var item in (ICollection<int>)source)
        {
            targetCollection.Add(item.Clone(flags, initializers));
        }
    }

    return target;
}

Isn't it quite like how you'd write your own Clone method for List<int>?

34
votes

If you're already using a 3rd party application like ValueInjecter or Automapper, you can do something like this:

MyObject oldObj; // The existing object to clone

MyObject newObj = new MyObject();
newObj.InjectFrom(oldObj); // Using ValueInjecter syntax

Using this method you don't have to implement ISerializable or ICloneable on your objects. This is common with the MVC/MVVM pattern, so simple tools like this have been created.

see the ValueInjecter deep cloning sample on GitHub.

32
votes

Well I was having problems using ICloneable in Silverlight, but I liked the idea of seralization, I can seralize XML, so I did this:

static public class SerializeHelper
{
    //Michael White, Holly Springs Consulting, 2009
    //[email protected]
    public static T DeserializeXML<T>(string xmlData) where T:new()
    {
        if (string.IsNullOrEmpty(xmlData))
            return default(T);

        TextReader tr = new StringReader(xmlData);
        T DocItms = new T();
        XmlSerializer xms = new XmlSerializer(DocItms.GetType());
        DocItms = (T)xms.Deserialize(tr);

        return DocItms == null ? default(T) : DocItms;
    }

    public static string SeralizeObjectToXML<T>(T xmlObject)
    {
        StringBuilder sbTR = new StringBuilder();
        XmlSerializer xmsTR = new XmlSerializer(xmlObject.GetType());
        XmlWriterSettings xwsTR = new XmlWriterSettings();

        XmlWriter xmwTR = XmlWriter.Create(sbTR, xwsTR);
        xmsTR.Serialize(xmwTR,xmlObject);

        return sbTR.ToString();
    }

    public static T CloneObject<T>(T objClone) where T:new()
    {
        string GetString = SerializeHelper.SeralizeObjectToXML<T>(objClone);
        return SerializeHelper.DeserializeXML<T>(GetString);
    }
}
29
votes

The best is to implement an extension method like

public static T DeepClone<T>(this T originalObject)
{ /* the cloning code */ }

and then use it anywhere in the solution by

var copy = anyObject.DeepClone();

We can have the following three implementations:

  1. By Serialization (the shortest code)
  2. By Reflection - 5x faster
  3. By Expression Trees - 20x faster

All linked methods are well working and were deeply tested.

23
votes

The short answer is you inherit from the ICloneable interface and then implement the .clone function. Clone should do a memberwise copy and perform a deep copy on any member that requires it, then return the resulting object. This is a recursive operation ( it requires that all members of the class you want to clone are either value types or implement ICloneable and that their members are either value types or implement ICloneable, and so on).

For a more detailed explanation on Cloning using ICloneable, check out this article.

The long answer is "it depends". As mentioned by others, ICloneable is not supported by generics, requires special considerations for circular class references, and is actually viewed by some as a "mistake" in the .NET Framework. The serialization method depends on your objects being serializable, which they may not be and you may have no control over. There is still much debate in the community over which is the "best" practice. In reality, none of the solutions are the one-size fits all best practice for all situations like ICloneable was originally interpreted to be.

See the this Developer's Corner article for a few more options (credit to Ian).

19
votes
  1. Basically you need to implement ICloneable interface and then realize object structure copying.
  2. If it's deep copy of all members, you need to insure (not relating on solution you choose) that all children are clonable as well.
  3. Sometimes you need to be aware of some restriction during this process, for example if you copying the ORM objects most of frameworks allow only one object attached to the session and you MUST NOT make clones of this object, or if it's possible you need to care about session attaching of these objects.

Cheers.

19
votes

EDIT: project is discontinued

If you want true cloning to unknown types you can take a look at fastclone.

That's expression based cloning working about 10 times faster than binary serialization and maintaining complete object graph integrity.

That means: if you refer multiple times to the same object in your hierachy, the clone will also have a single instance beeing referenced.

There is no need for interfaces, attributes or any other modification to the objects being cloned.

16
votes

Keep things simple and use AutoMapper as others mentioned, it's a simple little library to map one object to another... To copy an object to another with the same type, all you need is three lines of code:

MyType source = new MyType();
Mapper.CreateMap<MyType, MyType>();
MyType target = Mapper.Map<MyType, MyType>(source);

The target object is now a copy of the source object. Not simple enough? Create an extension method to use everywhere in your solution:

public static T Copy<T>(this T source)
{
    T copy = default(T);
    Mapper.CreateMap<T, T>();
    copy = Mapper.Map<T, T>(source);
    return copy;
}

The extension method can be used as follow:

MyType copy = source.Copy();
16
votes

DeepCloner: Quick, easy, effective NuGet package to solve cloning

After reading all answers I was surprised no one mentioned this excellent package:

DeepCloner GitHub project

DeepCloner NuGet package

Elaborating a bit on its README, here are the reason why we chose it at work:

  • It can deep or shallow copy
  • In deep cloning all object graph is maintained.
  • Uses code-generation in runtime, as result cloning is blazingly fast
  • Objects copied by internal structure, no methods or ctors called
  • You don't need to mark classes somehow (like Serializable-attribute, or implement interfaces)
  • No requirement to specify object type for cloning. Object can be casted to interface or as an abstract object (e.g. you can clone array of ints as abstract Array or IEnumerable; even null can be cloned without any errors)
  • Cloned object doesn't have any ability to determine that he is clone (except with very specific methods)

Usage:

var deepClone = new { Id = 1, Name = "222" }.DeepClone();
var shallowClone = new { Id = 1, Name = "222" }.ShallowClone();

Performance:

The README contains a performance comparison of various cloning libraries and methods: DeepCloner Performance.

Requirements:

  • .NET 4.0 or higher or .NET Standard 1.3 (.NET Core)
  • Requires Full Trust permission set or Reflection permission (MemberAccess)
11
votes

In general, you implement the ICloneable interface and implement Clone yourself. C# objects have a built-in MemberwiseClone method that performs a shallow copy that can help you out for all the primitives.

For a deep copy, there is no way it can know how to automatically do it.

10
votes

I came up with this to overcome a .NET shortcoming having to manually deep copy List<T>.

I use this:

static public IEnumerable<SpotPlacement> CloneList(List<SpotPlacement> spotPlacements)
{
    foreach (SpotPlacement sp in spotPlacements)
    {
        yield return (SpotPlacement)sp.Clone();
    }
}

And at another place:

public object Clone()
{
    OrderItem newOrderItem = new OrderItem();
    ...
    newOrderItem._exactPlacements.AddRange(SpotPlacement.CloneList(_exactPlacements));
    ...
    return newOrderItem;
}

I tried to come up with oneliner that does this, but it's not possible, due to yield not working inside anonymous method blocks.

Better still, use generic List<T> cloner:

class Utility<T> where T : ICloneable
{
    static public IEnumerable<T> CloneList(List<T> tl)
    {
        foreach (T t in tl)
        {
            yield return (T)t.Clone();
        }
    }
}
10
votes

Q. Why would I choose this answer?

  • Choose this answer if you want the fastest speed .NET is capable of.
  • Ignore this answer if you want a really, really easy method of cloning.

In other words, go with another answer unless you have a performance bottleneck that needs fixing, and you can prove it with a profiler.

10x faster than other methods

The following method of performing a deep clone is:

  • 10x faster than anything that involves serialization/deserialization;
  • Pretty darn close to the theoretical maximum speed .NET is capable of.

And the method ...

For ultimate speed, you can use Nested MemberwiseClone to do a deep copy. Its almost the same speed as copying a value struct, and is much faster than (a) reflection or (b) serialization (as described in other answers on this page).

Note that if you use Nested MemberwiseClone for a deep copy, you have to manually implement a ShallowCopy for each nested level in the class, and a DeepCopy which calls all said ShallowCopy methods to create a complete clone. This is simple: only a few lines in total, see the demo code below.

Here is the output of the code showing the relative performance difference for 100,000 clones:

  • 1.08 seconds for Nested MemberwiseClone on nested structs
  • 4.77 seconds for Nested MemberwiseClone on nested classes
  • 39.93 seconds for Serialization/Deserialization

Using Nested MemberwiseClone on a class almost as fast as copying a struct, and copying a struct is pretty darn close to the theoretical maximum speed .NET is capable of.

Demo 1 of shallow and deep copy, using classes and MemberwiseClone:
  Create Bob
    Bob.Age=30, Bob.Purchase.Description=Lamborghini
  Clone Bob >> BobsSon
  Adjust BobsSon details
    BobsSon.Age=2, BobsSon.Purchase.Description=Toy car
  Proof of deep copy: If BobsSon is a true clone, then adjusting BobsSon details will not affect Bob:
    Bob.Age=30, Bob.Purchase.Description=Lamborghini
  Elapsed time: 00:00:04.7795670,30000000

Demo 2 of shallow and deep copy, using structs and value copying:
  Create Bob
    Bob.Age=30, Bob.Purchase.Description=Lamborghini
  Clone Bob >> BobsSon
  Adjust BobsSon details:
    BobsSon.Age=2, BobsSon.Purchase.Description=Toy car
  Proof of deep copy: If BobsSon is a true clone, then adjusting BobsSon details will not affect Bob:
    Bob.Age=30, Bob.Purchase.Description=Lamborghini
  Elapsed time: 00:00:01.0875454,30000000

Demo 3 of deep copy, using class and serialize/deserialize:
  Elapsed time: 00:00:39.9339425,30000000

To understand how to do a deep copy using MemberwiseCopy, here is the demo project that was used to generate the times above:

// Nested MemberwiseClone example. 
// Added to demo how to deep copy a reference class.
[Serializable] // Not required if using MemberwiseClone, only used for speed comparison using serialization.
public class Person
{
    public Person(int age, string description)
    {
        this.Age = age;
        this.Purchase.Description = description;
    }
    [Serializable] // Not required if using MemberwiseClone
    public class PurchaseType
    {
        public string Description;
        public PurchaseType ShallowCopy()
        {
            return (PurchaseType)this.MemberwiseClone();
        }
    }
    public PurchaseType Purchase = new PurchaseType();
    public int Age;
    // Add this if using nested MemberwiseClone.
    // This is a class, which is a reference type, so cloning is more difficult.
    public Person ShallowCopy()
    {
        return (Person)this.MemberwiseClone();
    }
    // Add this if using nested MemberwiseClone.
    // This is a class, which is a reference type, so cloning is more difficult.
    public Person DeepCopy()
    {
            // Clone the root ...
        Person other = (Person) this.MemberwiseClone();
            // ... then clone the nested class.
        other.Purchase = this.Purchase.ShallowCopy();
        return other;
    }
}
// Added to demo how to copy a value struct (this is easy - a deep copy happens by default)
public struct PersonStruct
{
    public PersonStruct(int age, string description)
    {
        this.Age = age;
        this.Purchase.Description = description;
    }
    public struct PurchaseType
    {
        public string Description;
    }
    public PurchaseType Purchase;
    public int Age;
    // This is a struct, which is a value type, so everything is a clone by default.
    public PersonStruct ShallowCopy()
    {
        return (PersonStruct)this;
    }
    // This is a struct, which is a value type, so everything is a clone by default.
    public PersonStruct DeepCopy()
    {
        return (PersonStruct)this;
    }
}
// Added only for a speed comparison.
public class MyDeepCopy
{
    public static T DeepCopy<T>(T obj)
    {
        object result = null;
        using (var ms = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);
            ms.Position = 0;
            result = (T)formatter.Deserialize(ms);
            ms.Close();
        }
        return (T)result;
    }
}

Then, call the demo from main:

void MyMain(string[] args)
{
    {
        Console.Write("Demo 1 of shallow and deep copy, using classes and MemberwiseCopy:\n");
        var Bob = new Person(30, "Lamborghini");
        Console.Write("  Create Bob\n");
        Console.Write("    Bob.Age={0}, Bob.Purchase.Description={1}\n", Bob.Age, Bob.Purchase.Description);
        Console.Write("  Clone Bob >> BobsSon\n");
        var BobsSon = Bob.DeepCopy();
        Console.Write("  Adjust BobsSon details\n");
        BobsSon.Age = 2;
        BobsSon.Purchase.Description = "Toy car";
        Console.Write("    BobsSon.Age={0}, BobsSon.Purchase.Description={1}\n", BobsSon.Age, BobsSon.Purchase.Description);
        Console.Write("  Proof of deep copy: If BobsSon is a true clone, then adjusting BobsSon details will not affect Bob:\n");
        Console.Write("    Bob.Age={0}, Bob.Purchase.Description={1}\n", Bob.Age, Bob.Purchase.Description);
        Debug.Assert(Bob.Age == 30);
        Debug.Assert(Bob.Purchase.Description == "Lamborghini");
        var sw = new Stopwatch();
        sw.Start();
        int total = 0;
        for (int i = 0; i < 100000; i++)
        {
            var n = Bob.DeepCopy();
            total += n.Age;
        }
        Console.Write("  Elapsed time: {0},{1}\n\n", sw.Elapsed, total);
    }
    {               
        Console.Write("Demo 2 of shallow and deep copy, using structs:\n");
        var Bob = new PersonStruct(30, "Lamborghini");
        Console.Write("  Create Bob\n");
        Console.Write("    Bob.Age={0}, Bob.Purchase.Description={1}\n", Bob.Age, Bob.Purchase.Description);
        Console.Write("  Clone Bob >> BobsSon\n");
        var BobsSon = Bob.DeepCopy();
        Console.Write("  Adjust BobsSon details:\n");
        BobsSon.Age = 2;
        BobsSon.Purchase.Description = "Toy car";
        Console.Write("    BobsSon.Age={0}, BobsSon.Purchase.Description={1}\n", BobsSon.Age, BobsSon.Purchase.Description);
        Console.Write("  Proof of deep copy: If BobsSon is a true clone, then adjusting BobsSon details will not affect Bob:\n");
        Console.Write("    Bob.Age={0}, Bob.Purchase.Description={1}\n", Bob.Age, Bob.Purchase.Description);                
        Debug.Assert(Bob.Age == 30);
        Debug.Assert(Bob.Purchase.Description == "Lamborghini");
        var sw = new Stopwatch();
        sw.Start();
        int total = 0;
        for (int i = 0; i < 100000; i++)
        {
            var n = Bob.DeepCopy();
            total += n.Age;
        }
        Console.Write("  Elapsed time: {0},{1}\n\n", sw.Elapsed, total);
    }
    {
        Console.Write("Demo 3 of deep copy, using class and serialize/deserialize:\n");
        int total = 0;
        var sw = new Stopwatch();
        sw.Start();
        var Bob = new Person(30, "Lamborghini");
        for (int i = 0; i < 100000; i++)
        {
            var BobsSon = MyDeepCopy.DeepCopy<Person>(Bob);
            total += BobsSon.Age;
        }
        Console.Write("  Elapsed time: {0},{1}\n", sw.Elapsed, total);
    }
    Console.ReadKey();
}

Again, note that if you use Nested MemberwiseClone for a deep copy, you have to manually implement a ShallowCopy for each nested level in the class, and a DeepCopy which calls all said ShallowCopy methods to create a complete clone. This is simple: only a few lines in total, see the demo code above.

Value types vs. References Types

Note that when it comes to cloning an object, there is is a big difference between a "struct" and a "class":

  • If you have a "struct", it's a value type so you can just copy it, and the contents will be cloned (but it will only make a shallow clone unless you use the techniques in this post).
  • If you have a "class", it's a reference type, so if you copy it, all you are doing is copying the pointer to it. To create a true clone, you have to be more creative, and use differences between value types and references types which creates another copy of the original object in memory.

See differences between value types and references types.

Checksums to aid in debugging

  • Cloning objects incorrectly can lead to very difficult-to-pin-down bugs. In production code, I tend to implement a checksum to double check that the object has been cloned properly, and hasn't been corrupted by another reference to it. This checksum can be switched off in Release mode.
  • I find this method quite useful: often, you only want to clone parts of the object, not the entire thing.

Really useful for decoupling many threads from many other threads

One excellent use case for this code is feeding clones of a nested class or struct into a queue, to implement the producer / consumer pattern.

  • We can have one (or more) threads modifying a class that they own, then pushing a complete copy of this class into a ConcurrentQueue.
  • We then have one (or more) threads pulling copies of these classes out and dealing with them.

This works extremely well in practice, and allows us to decouple many threads (the producers) from one or more threads (the consumers).

And this method is blindingly fast too: if we use nested structs, it's 35x faster than serializing/deserializing nested classes, and allows us to take advantage of all of the threads available on the machine.

Update

Apparently, ExpressMapper is as fast, if not faster, than hand coding such as above. I might have to see how they compare with a profiler.

8
votes

Here is a deep copy implementation:

public static object CloneObject(object opSource)
{
    //grab the type and create a new instance of that type
    Type opSourceType = opSource.GetType();
    object opTarget = CreateInstanceOfType(opSourceType);

    //grab the properties
    PropertyInfo[] opPropertyInfo = opSourceType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

    //iterate over the properties and if it has a 'set' method assign it from the source TO the target
    foreach (PropertyInfo item in opPropertyInfo)
    {
        if (item.CanWrite)
        {
            //value types can simply be 'set'
            if (item.PropertyType.IsValueType || item.PropertyType.IsEnum || item.PropertyType.Equals(typeof(System.String)))
            {
                item.SetValue(opTarget, item.GetValue(opSource, null), null);
            }
            //object/complex types need to recursively call this method until the end of the tree is reached
            else
            {
                object opPropertyValue = item.GetValue(opSource, null);
                if (opPropertyValue == null)
                {
                    item.SetValue(opTarget, null, null);
                }
                else
                {
                    item.SetValue(opTarget, CloneObject(opPropertyValue), null);
                }
            }
        }
    }
    //return the new item
    return opTarget;
}
8
votes

As I couldn't find a cloner that meets all my requirements in different projects, I created a deep cloner that can be configured and adapted to different code structures instead of adapting my code to meet the cloners requirements. Its achieved by adding annotations to the code that shall be cloned or you just leave the code as it is to have the default behaviour. It uses reflection, type caches and is based on fasterflect. The cloning process is very fast for a huge amount of data and a high object hierarchy (compared to other reflection/serialization based algorithms).

https://github.com/kalisohn/CloneBehave

Also available as a nuget package: https://www.nuget.org/packages/Clone.Behave/1.0.0

For example: The following code will deepClone Address, but only perform a shallow copy of the _currentJob field.

public class Person 
{
  [DeepClone(DeepCloneBehavior.Shallow)]
  private Job _currentJob;      

  public string Name { get; set; }

  public Job CurrentJob 
  { 
    get{ return _currentJob; }
    set{ _currentJob = value; }
  }

  public Person Manager { get; set; }
}

public class Address 
{      
  public Person PersonLivingHere { get; set; }
}

Address adr = new Address();
adr.PersonLivingHere = new Person("John");
adr.PersonLivingHere.BestFriend = new Person("James");
adr.PersonLivingHere.CurrentJob = new Job("Programmer");

Address adrClone = adr.Clone();

//RESULT
adr.PersonLivingHere == adrClone.PersonLivingHere //false
adr.PersonLivingHere.Manager == adrClone.PersonLivingHere.Manager //false
adr.PersonLivingHere.CurrentJob == adrClone.PersonLivingHere.CurrentJob //true
adr.PersonLivingHere.CurrentJob.AnyProperty == adrClone.PersonLivingHere.CurrentJob.AnyProperty //true
8
votes

Disclaimer: I'm the author of the mentioned package.

I was surprised how the top answers to this question in 2019 still use serialization or reflection.

Serialization is limiting (requires attributes, specific constructors, etc.) and is very slow

BinaryFormatter requires the Serializable attribute, JsonConverter requires a parameterless constructor or attributes, neither handle read only fields or interfaces very well and both are 10-30x slower than necessary.

Expression Trees

You can instead use Expression Trees or Reflection.Emit to generate cloning code only once, then use that compiled code instead of slow reflection or serialization.

Having come across the problem myself and seeing no satisfactory solution, I decided to create a package that does just that and works with every type and is a almost as fast as custom written code.

You can find the project on GitHub: https://github.com/marcelltoth/ObjectCloner

Usage

You can install it from NuGet. Either get the ObjectCloner package and use it as:

var clone = ObjectCloner.DeepClone(original);

or if you don't mind polluting your object type with extensions get ObjectCloner.Extensions as well and write:

var clone = original.DeepClone();

Performance

A simple benchmark of cloning a class hierarchy showed performance ~3x faster than using Reflection, ~12x faster than Newtonsoft.Json serialization and ~36x faster than the highly suggested BinaryFormatter.

7
votes

I've seen it implemented through reflection as well. Basically there was a method that would iterate through the members of an object and appropriately copy them to the new object. When it reached reference types or collections I think it did a recursive call on itself. Reflection is expensive, but it worked pretty well.

7
votes

Code Generator

We have seen a lot of ideas from serialization over manual implementation to reflection and I want to propose a totally different approach using the CGbR Code Generator. The generate clone method is memory and CPU efficient and therefor 300x faster as the standard DataContractSerializer.

All you need is a partial class definition with ICloneable and the generator does the rest:

public partial class Root : ICloneable
{
    public Root(int number)
    {
        _number = number;
    }
    private int _number;

    public Partial[] Partials { get; set; }

    public IList<ulong> Numbers { get; set; }

    public object Clone()
    {
        return Clone(true);
    }

    private Root()
    {
    }
} 

public partial class Root
{
    public Root Clone(bool deep)
    {
        var copy = new Root();
        // All value types can be simply copied
        copy._number = _number; 
        if (deep)
        {
            // In a deep clone the references are cloned 
            var tempPartials = new Partial[Partials.Length];
            for (var i = 0; i < Partials.Length; i++)
            {
                var value = Partials[i];
                value = value.Clone(true);
                tempPartials[i] = value;
            }
            copy.Partials = tempPartials;
            var tempNumbers = new List<ulong>(Numbers.Count);
            for (var i = 0; i < Numbers.Count; i++)
            {
                var value = Numbers[i];
                tempNumbers.Add(value);
            }
            copy.Numbers = tempNumbers;
        }
        else
        {
            // In a shallow clone only references are copied
            copy.Partials = Partials; 
            copy.Numbers = Numbers; 
        }
        return copy;
    }
}

Note: Latest version has a more null checks, but I left them out for better understanding.

6
votes

I like Copyconstructors like that:

    public AnyObject(AnyObject anyObject)
    {
        foreach (var property in typeof(AnyObject).GetProperties())
        {
            property.SetValue(this, property.GetValue(anyObject));
        }
        foreach (var field in typeof(AnyObject).GetFields())
        {
            field.SetValue(this, field.GetValue(anyObject));
        }
    }

If you have more things to copy add them

6
votes

This method solved the problem for me:

private static MyObj DeepCopy(MyObj source)
        {

            var DeserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };

            return JsonConvert.DeserializeObject<MyObj >(JsonConvert.SerializeObject(source), DeserializeSettings);

        }

Use it like this: MyObj a = DeepCopy(b);

6
votes

Here a solution fast and easy that worked for me without relaying on Serialization/Deserialization.

public class MyClass
{
    public virtual MyClass DeepClone()
    {
        var returnObj = (MyClass)MemberwiseClone();
        var type = returnObj.GetType();
        var fieldInfoArray = type.GetRuntimeFields().ToArray();

        foreach (var fieldInfo in fieldInfoArray)
        {
            object sourceFieldValue = fieldInfo.GetValue(this);
            if (!(sourceFieldValue is MyClass))
            {
                continue;
            }

            var sourceObj = (MyClass)sourceFieldValue;
            var clonedObj = sourceObj.DeepClone();
            fieldInfo.SetValue(returnObj, clonedObj);
        }
        return returnObj;
    }
}

EDIT: requires

    using System.Linq;
    using System.Reflection;

That's How I used it

public MyClass Clone(MyClass theObjectIneededToClone)
{
    MyClass clonedObj = theObjectIneededToClone.DeepClone();
}
6
votes

Create an extension:

public static T Clone<T>(this T theObject)
{
    string jsonData = JsonConvert.SerializeObject(theObject);
    return JsonConvert.DeserializeObject<T>(jsonData);
}

And call it like this:

NewObject = OldObject.Clone();
5
votes

Follow these steps:

  • Define an ISelf<T> with a read-only Self property that returns T, and ICloneable<out T>, which derives from ISelf<T> and includes a method T Clone().
  • Then define a CloneBase type which implements a protected virtual generic VirtualClone casting MemberwiseClone to the passed-in type.
  • Each derived type should implement VirtualClone by calling the base clone method and then doing whatever needs to be done to properly clone those aspects of the derived type which the parent VirtualClone method hasn't yet handled.

For maximum inheritance versatility, classes exposing public cloning functionality should be sealed, but derive from a base class which is otherwise identical except for the lack of cloning. Rather than passing variables of the explicit clonable type, take a parameter of type ICloneable<theNonCloneableType>. This will allow a routine that expects a cloneable derivative of Foo to work with a cloneable derivative of DerivedFoo, but also allow the creation of non-cloneable derivatives of Foo.

5
votes

I think you can try this.

MyObject myObj = GetMyObj(); // Create and fill a new object
MyObject newObj = new MyObject(myObj); //DeepClone it
4
votes

I have created a version of the accepted answer that works with both '[Serializable]' and '[DataContract]'. It has been a while since I wrote it, but if I remember correctly [DataContract] needed a different serializer.

Requires System, System.IO, System.Runtime.Serialization, System.Runtime.Serialization.Formatters.Binary, System.Xml;

public static class ObjectCopier
{

    /// <summary>
    /// Perform a deep Copy of an object that is marked with '[Serializable]' or '[DataContract]'
    /// </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 == true)
        {
            return CloneUsingSerializable<T>(source);
        }

        if (IsDataContract(typeof(T)) == true)
        {
            return CloneUsingDataContracts<T>(source);
        }

        throw new ArgumentException("The type must be Serializable or use DataContracts.", "source");
    }


    /// <summary>
    /// Perform a deep Copy of an object that is marked with '[Serializable]'
    /// </summary>
    /// <remarks>
    /// Found on http://stackoverflow.com/questions/78536/cloning-objects-in-c-sharp
    /// Uses code found on CodeProject, which allows free use in third party apps
    /// - http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
    /// </remarks>
    /// <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 CloneUsingSerializable<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);
        }
    }


    /// <summary>
    /// Perform a deep Copy of an object that is marked with '[DataContract]'
    /// </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 CloneUsingDataContracts<T>(T source)
    {
        if (IsDataContract(typeof(T)) == false)
        {
            throw new ArgumentException("The type must be a data contract.", "source");
        }

        // ** Don't serialize a null object, simply return the default for that object
        if (Object.ReferenceEquals(source, null))
        {
            return default(T);
        }

        DataContractSerializer dcs = new DataContractSerializer(typeof(T));
        using(Stream stream = new MemoryStream())
        {
            using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream))
            {
                dcs.WriteObject(writer, source);
                writer.Flush();
                stream.Seek(0, SeekOrigin.Begin);
                using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
                {
                    return (T)dcs.ReadObject(reader);
                }
            }
        }
    }


    /// <summary>
    /// Helper function to check if a class is a [DataContract]
    /// </summary>
    /// <param name="type">The type of the object to check.</param>
    /// <returns>Boolean flag indicating if the class is a DataContract (true) or not (false) </returns>
    public static bool IsDataContract(Type type)
    {
        object[] attributes = type.GetCustomAttributes(typeof(DataContractAttribute), false);
        return attributes.Length == 1;
    }

}