Deep cloning objects

929,477

Solution 1

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(source, 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(source, 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);
}

Solution 2

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);
    }
}

Solution 3

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.

Solution 4

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.

Solution 5

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

Share:
929,477
NakedBrunch
Author by

NakedBrunch

C#/VB .NET web Developer with a focus on dynamic communication solutions.

Updated on April 14, 2022

Comments

  • NakedBrunch
    NakedBrunch about 2 years

    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?

    • Pedro77
      Pedro77 over 12 years
      May be useful: "Why Copying an Object is a terrible thing to do?" agiledeveloper.com/articles/cloning072002.htm
    • Felix K.
      Felix K. about 12 years
    • Daniel Little
      Daniel Little over 11 years
      You should have a look at AutoMapper
    • Pedro77
      Pedro77 almost 11 years
      Your solution is far more complex, I got lost reading it... hehehe. I'm using an DeepClone interface. public interface IDeepCloneable<T> { T DeepClone(); }
    • supercat
      supercat about 10 years
      @Pedro77: A concern I have with IDeepCloneable is that not all collections of references to things that can be deep-cloned should be; the proper behavior when cloning a List<T> depends not just upon T, but also upon the purpose of the lists. If none of the items in the lists will ever be exposed to anything which would mutate them, then even if the items within the lists could be cloned, it would be better to copy the references directly.
    • Alex Burtsev
      Alex Burtsev almost 10 years
      This question is also answered here stackoverflow.com/q/129389/235715
    • ruffin
      ruffin over 9 years
      @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. ;^)
    • Mertuarez
      Mertuarez about 8 years
      If you need this perhaps you have wrong implementation. And if you use dependency injection it does not make sense at all.
    • C Perkins
      C Perkins about 7 years
      In this end, this question and all the answers are about as useful as "How do I code a class?" There are many answers, but there is no single correct answer despite votes. This is NOT to say that no answer is useful or the question not work asking, but beware of polarized answers. The biggest deficit here is emphasis on providing detailed documentation and for the user/implementer of a class to take responsibility for understanding the details of any copy operation.
    • Szabolcs Páll
      Szabolcs Páll over 6 years
      Why not just getting a new instance of it? Or if you wanna copy an object you modified rather than just instantiated you might as well create a method that does all of it, and just call that method twice.
    • himanshupareek66
      himanshupareek66 over 6 years
      Call the MemberwiseClone method to create a shallow copy of an object, and then assign new objects whose values are the same as the original object to any properties or fields whose values are reference types. The DeepCopy method in the example illustrates this approach. msdn.microsoft.com/en-us/library/…
    • Ahmed Sabry
      Ahmed Sabry over 5 years
      Check this Answer: stackoverflow.com/a/52097307/4707576 about: Cloning objects without Serialization
  • Karg
    Karg over 15 years
    ICloneable doesn't have a generic interface, so it is not recommended to use that interface.
  • Karg
    Karg over 15 years
    ICloneable doesn't have a generic interface, so it is not recommended to use that interface.
  • Pop Catalin
    Pop Catalin over 15 years
    .Net doesn't have copy constructors.
  • Pop Catalin
    Pop Catalin over 15 years
    Your solution works until it needs to handle circular references, then things start to complicate, it's better to try implement deep cloning using deep serialization.
  • Nick
    Nick over 15 years
    Sure it does: new MyObject(objToCloneFrom) Just declare a ctor which takes the object to clone as a parameter.
  • Raymond
    Raymond over 15 years
    stackoverflow.com/questions/78536/cloning-objects-in-c/… has a link to the code above [and references two other such implementations, one of which is more appropriate in my context]
  • Dave Van den Eynde
    Dave Van den Eynde almost 15 years
    It's not the same thing. You have to add it to every class manually, and you don't even know if you're garantueeing a deep copy.
  • Jakob Dam Jensen
    Jakob Dam Jensen over 14 years
    +1 for copy ctor. You have to manually write a clone() function for each type of object too, and good luck with that when your class hierarchy gets a few levels deep.
  • 3Dave
    3Dave over 14 years
    Serialization/deserialization involves significant overhead that isn't necessary. See the ICloneable interface and .MemberWise() clone methods in C#.
  • johnc
    johnc over 14 years
    @David, granted, but if the objects are light, and the performance hit when using it is not too high for your requirements, then it is a useful tip. I haven't used it intensively with large amounts of data in a loop, I admit, but I have never seen a single performance concern.
  • 3Dave
    3Dave over 14 years
    @johnc I like your response because it'll work almost every time, but as an embedded systems guy, and mid-90's x86 assembly language graphics nut, optimization is always on my mind. Just remember that deserialization involves costly string processing and reflection, and that some property types - like Dictionaries - can't be serialized/deserialized. Still, very good response that I upvoted. ("Just remember" is for the peanut gallery).
  • Peder Rice
    Peder Rice over 13 years
    I'd simply add that one doesn't always have access to an object to be able to implement an ICloneable interface, so this solution comes in handy.
  • supercat
    supercat over 13 years
    I'm not clear why ICloneable is considered vague. Given a type like Dictionary(Of T,U), I would expect that ICloneable.Clone should do whatever level of deep and shallow copying is necessary to make the new dictionary be an independent dictionary that contains the same T's and U's (struct contents, and/or object references) as the original. Where's the ambiguity? To be sure, a generic ICloneable(Of T), which inherited ISelf(Of T), which included a "Self" method, would be much better, but I don't see ambiguity on deep vs shallow cloning.
  • andriy
    andriy over 13 years
    Your example illustrates the problem. Suppose you have a Dictionary<string, Customer>. Should the cloned Dictionary have the same Customer objects as the original, or copies of those Customer objects? There are reasonable use cases for either one. But ICloneable doesn't make clear which one you'll get. That's why it's not useful.
  • Amir Rezaei
    Amir Rezaei over 13 years
    Instead of "if (!typeof(T).IsSerializable)" you can write "public static T Clone<T>(T source) where T : ISerializable
  • Daniel Gehriger
    Daniel Gehriger almost 13 years
    @Amir: actually, no: typeof(T).IsSerializable is also true if the type has been marked with the [Serializable] attribute. It doesn't have to implement the ISerializable interface.
  • Jerry Nixon
    Jerry Nixon almost 13 years
    I recommend this method signature: public static T Copy<T>(this T item) where T: ISerializable
  • epalm
    epalm almost 13 years
    As mentioned here you'll have to mark unserializable private fields/events as [NonSerialized] (or [field: NonSerialized]) for this to work.
  • johnc
    johnc almost 13 years
    @epalm, certainly a passable knowledge of Serialization is required, but it's a fairly easy learning curve
  • Alex Norcliffe
    Alex Norcliffe over 12 years
    Just thought I'd mention that whilst this method is useful, and I've used it myself many a time, it's not at all compatible with Medium Trust - so watch out if you're writing code that needs compatibility. BinaryFormatter access private fields and thus cannot work in the default permissionset for partial trust environments. You could try another serializer, but make sure your caller knows that the clone may not be perfect if the incoming object relies on private fields.
  • Alex Norcliffe
    Alex Norcliffe over 12 years
    This, unfortunately, is flawed. It's equivalent to calling objectOne.MyProperty = objectTwo.MyProperty (i.e., it will just copy the reference across). It will not clone the values of the properties.
  • sll
    sll over 12 years
    This looks like memberwise clone because does not aware of reference type properties
  • Will
    Will over 12 years
    With copy constructors you lose hierarchy though. agiledeveloper.com/articles/cloning072002.htm
  • Contango
    Contango over 12 years
    If you want blindingly fast performance, don't go for this implementation: it uses reflection, so it won't be that fast. Conversely, "premature optmization is the of all evil", so ignore the performance side until after you've run a profiler.
  • IAbstract
    IAbstract over 12 years
    I like the copy constructor; but suppose you have an AbstractBaseType, with 3 derived types, each nested such that Type1:AbstractBaseType has a Type2:AbstractBaseType member, which has a Type3:AbstractBaseType member. Now you have to check the types.
  • Felix K.
    Felix K. about 12 years
  • Konstantin Salavatov
    Konstantin Salavatov about 12 years
    to Alex Norcliffe : author of question asked about "copying each property" rather then cloning. in most cases exact duplication of properties is not needed.
  • Kelly
    Kelly almost 12 years
    @David Lively while I know this isn't any faster: if you serialize to JSON instead you can indeed serialize a dictionary, I do it all the time.
  • cregox
    cregox over 11 years
    Johnc, to @RubenBartelink 's credit, the right number there would be 8 (I suppose), and not 78611 (though I loved the clever reference to own post). But clearly you were writing this very elegant answer while other people were giving one liners and links and even 3 links for such a topic is already quite a big number to read through.
  • Raymond
    Raymond over 11 years
    @Cawas Ah, I finally see it now! I have no idea if the votes were as skewed back in the day, but I continue to prefer Ian P's answer as it points to the source (this one didn't originally I'm guessing) and I'm willing to take 2 minutes to pick a strategy when the cited article has a very deep analysis of the different ways of doing it.
  • cregox
    cregox over 11 years
    @RubenBartelink and how about my brand new answer? :P
  • Koryu
    Koryu almost 11 years
    i think about using this method but with recursion. so if the value of a property is a reference, create a new object and call CopyTo again. i just see one problem, that all used classes must have a constructor without parameters. Anybody tried this already? i also wonder if this will actually work with properties containing .net classes like DataRow and DataTable?
  • C.B.
    C.B. over 10 years
    @IAbstract : Why should you have to check the types? Just rely on inheritance: pastebin.com/XWGQFBhr ...
  • IAbstract
    IAbstract over 10 years
    Descendants may require different logic and will require some if-then or switch logic. Otherwise, you have to provide a corresponding base constructor to deep clone. Clone constructors are just messy.
  • C.B.
    C.B. over 10 years
    @IAbstract : <s>Why should you have to check the types? Just rely on inheritance: pastebin.com/XWGQFBhr ...</s> Nevermind, after reading Will's link, i understand the issue you tried to express: members of type AbstractBaseType cannot be cloned via some copy-constructor in ABT, their copies would need to be created through their particular type's copy-constructor...
  • esskar
    esskar about 10 years
    the solutiojn is even faster than the BinaryFormatter solution, .NET Serialization Performance Comparison
  • crush
    crush almost 10 years
    @PederRice For that very reason, it might not be possible to mark a class as Serializable either. In that case, you'd need a solution which uses reflection.
  • crush
    crush almost 10 years
    @Kyralessa The Microsoft MSDN article actually states this very problem of not knowing if you are requesting a deep or shallow copy.
  • crush
    crush almost 10 years
    The problem with Copy Constructor's and Clone/Copy hand written methods is maintenance. Maintenance that is prone to error. Imagine a DataContract with 50+ fields. Imagine you then go to add a new field, or fields. It can become a cluster-f* real fast. Any change you make to the class, you must also remember to make to the copy constructor. This is why it is better to leave copying up to something like serialization or reflection. It would be nice if C# would add in the functionality for Deep Copy itself, but I believe they left it out because defining what is a Deep Copy isn't cut and dried
  • crush
    crush almost 10 years
    What are the chances of this getting on NuGet? It seems like the best solution. How does it compare to NClone?
  • Mark Ewer
    Mark Ewer almost 10 years
    Thanks for this. I was able to do essentially the same thing with the BSON serializer that ships with the MongoDB driver for C#.
  • odyth
    odyth over 9 years
    MemberwiseClone method creates a shallow copy NOT a deep copy. msdn.microsoft.com/en-us/library/…
  • BateTech
    BateTech over 9 years
    MS recommends not using ICloneable for public members. "Because callers of Clone cannot depend on the method performing a predictable cloning operation, we recommend that ICloneable not be implemented in public APIs." msdn.microsoft.com/en-us/library/… However, based on the explanation given by Venkat Subramaniam in your linked article, I think it makes sense to use in this situation as long as the creators of the ICloneable objects have a deep understanding of which properties should be deep vs. shallow copies (i.e. deep copy Brain, shallow copy City)
  • cregox
    cregox over 9 years
    First off, I'm far from an expert in this topic (public APIs). I think for once that MS remark makes a lot of sense. And I don't think it's safe to assume the users of that API will have such a deep understanding. So, it only makes sense implementing it on a public API if it really won't matter for whoever is going to use it. I guess having some kind of UML very explicitly making the distinction on each property could help. But I'd like to hear from someone with more experience. :P
  • Pierre
    Pierre over 9 years
    This is the best way for me, However, I use Newtonsoft.Json.JsonConvert but it is the same
  • LuckyLikey
    LuckyLikey about 9 years
    This one seems to be pretty useful
  • TarmoPikaro
    TarmoPikaro about 9 years
    It's easier to start working from one code snapshot than for overall system, especially closed one. It's quite understandable that no library can solve all problems with one shot. Some relaxations should be made.
  • Lasse V. Karlsen
    Lasse V. Karlsen almost 9 years
    If you copy a struct you get a shallow copy, you might still need specific implementation for a deep copy.
  • Contango
    Contango almost 9 years
    @Lasse V. Karlsen. Yes, you're absolutely correct, I've updated the answer to make this clearer. This method can be used to make deep copies of structs and classes. You can run the included example demo code to show how its done, it has an example of deep cloning a nested struct, and another example of deep cloning a nested class.
  • itadapter DKh
    itadapter DKh almost 9 years
    The JSON approach is Ok for small flat objects, but the original question was about any object, including the deep ones. The NFX.Slim serializer works orders of magnitude faster on any .NET type as long as it does not have delegates and unmanaged pointers, here is the source that works very much like BinaryFormnatter only at least 5 times faster: github.com/aumcode/nfx/blob/master/Source/NFX/Serialization/‌​… The test suite: github.com/aumcode/serbench proves that the only serialier which is faster is Protobuf which lacks type dynamism and references
  • nightcoder
    nightcoder almost 9 years
    I think this answer should be upvoted more times. Manually implementing ICloneable is tedious and error-prone, using reflection or serialization is slow if performance is important and you need to copy thousands of objects during a short period of time.
  • nightcoder
    nightcoder almost 9 years
    I've tried your solution and it seems to work well, thanks! I think this answer should be upvoted more times. Manually implementing ICloneable is tedious and error-prone, using reflection or serialization is slow if performance is important and you need to copy thousands of objects during a short period of time.
  • wal5hy
    wal5hy over 8 years
    Using a constructor means Copy/Clone cannot be part of an interface
  • MonsterMMORPG
    MonsterMMORPG over 8 years
    CreateInstanceOfType is not defined?
  • Roma Borodov
    Roma Borodov over 8 years
    Not at all, you wrong about reflection, you should simply cache this properly. Check my answer below stackoverflow.com/a/34368738/4711853
  • Mr.B
    Mr.B almost 8 years
    It fails on interger: "Non-static method requires a target."
  • Toxantron
    Toxantron almost 8 years
    You can use the CGbR Clone Generator and get a similar result without manually writing the code.
  • Simon Tewsi
    Simon Tewsi almost 8 years
    Tried recasting with an object with properties with simple types and reference types. Only did a shallow copy of the property that was a reference type.
  • Jaylen
    Jaylen almost 8 years
    This does not work when your object is an interface.
  • Tseng
    Tseng over 7 years
    Calling prop.GetValue(...) is still reflection and can't be cached. In an expression tree its compiled though, so faster
  • Anya Hope
    Anya Hope over 7 years
    Can I add that if you want to serialize custom objects, you will need to decorate all the properties with [DataMember] and the class with [DataContract]
  • Agorilla
    Agorilla about 7 years
    Be careful with this one, it performs really poorly. I ended up switching to johnc answer which is as short as this one and performs a lot better.
  • M.A.R.
    M.A.R. about 7 years
    A link to a solution is welcome, but please ensure your answer is useful without it: add context around the link so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. Answers that are little more than a link may be deleted.
  • Mrinal Kamboj
    Mrinal Kamboj over 6 years
    cloning code using Expression trees that you have posted codeproject.com/Articles/1111658/…, is failing with newer versions of .Net framework with a security exception, Operation could destabilize the runtime, it is basically an exception due to malformed expression tree, which is used to generate the Func at runtime, please check if you have some solution.In fact I have seen issue only with complex objects with deep hierarchy, simple one easily get copied
  • Michael Freidgeim
    Michael Freidgeim over 6 years
    The answer from the duplicate stackoverflow.com/questions/129389/… describes Copy extension, based on recursive MembershipClone
  • Michael Freidgeim
    Michael Freidgeim over 6 years
    Intermediate Language implementation is useful
  • radomeit
    radomeit about 6 years
    For this to work the object to clone needs to be serializable as already mentioned - this also means for example that it may not have circular dependencies
  • DavidGuaita
    DavidGuaita about 6 years
    Simple and concise answers are the best.
  • Konrad
    Konrad over 5 years
    There's no final in C#
  • Konrad
    Konrad over 5 years
    @DaveVandenEynde in C++ you have to add it manually too.en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming‌​)
  • Michael Brown
    Michael Brown over 5 years
    I tried it and it didn't work at all for me. Throws a MemberAccess exception.
  • Michael Sander
    Michael Sander over 5 years
    It doesn't work with newer versions of .NET and is discontinued
  • Artemious
    Artemious over 5 years
    Thanks for the different approaches performance comparison from the article codeproject.com/Articles/1111658/…
  • mr5
    mr5 over 5 years
    I think this is the best solution as the implementation can be applied on most programming languages.
  • N73k
    N73k almost 5 years
    This only does a shallow copy.
  • N73k
    N73k almost 5 years
    ExpressionTree implementation seems very good. It even works with circular references and private members. No attributes needed. Best answer I've found.
  • Ted Mucuzany
    Ted Mucuzany almost 5 years
    It really is. It can cause tricky side-effects, so it should be use carefully.
  • marbel82
    marbel82 almost 5 years
    In DeserializeObject() you should add additional options new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace}, because default constructor can change something that's not in the source 🔗
  • andriy
    andriy over 4 years
    @BateTech That goes against the principle that people shouldn't have to "just remember" things. Instead of using ICloneable, it makes more sense to define your own interface and methods to do exactly what you want. Then you can clearly document in the XML comments precisely what kind of cloning/copying it does. Incidentally, in some 15 years of .NET in a variety of jobs and industries I've almost never needed to clone/copy anything.
  • BateTech
    BateTech over 4 years
    @RyanLundy I agree to a certain extent, but I would argue that huge percentage of successful programming is "just remembering/knowing" things (including remembering to add XML comments, which interfaces to use, anit-patterns, etc.). Whether you use iCloneable or iMyCustomDeepClone, you still have to deal with which properties should be deep vs. shallow copies in the implementation of that interface, bc in a lot of cases it isn't going to be all deep or all shallow at the property level. That was the intent of my comment was that whomever implements the interface needs that understanding.
  • Adel Mourad
    Adel Mourad over 4 years
    The best answer, worked very well, you saved my day
  • EduLopez
    EduLopez almost 4 years
    This question is quite old. I think this answer should go up so people can actually see the value here.
  • ahmed hamdy
    ahmed hamdy almost 4 years
    @odyth important comment as actual code Do shallow copy, Here good article about Clone and examples for every type geeksforgeeks.org/shallow-copy-and-deep-copy-in-c-sharp
  • JamesHoux
    JamesHoux almost 4 years
    The reason Serialization is still popular in 2019 is because code generation ONLY works in trusted environments. This means it won't work in Unity or iOS and probably never will. So code generation is non-portable.
  • Cubelaster
    Cubelaster over 3 years
    I'd also like to add AutoMapper to the list. It would be considered as 3rd party tool, but since I find it amazing already, here's another use for it.
  • Ramil Aliyev
    Ramil Aliyev over 3 years
    I used NewtonSoft's 12.0.3 version, my class's hasn't parameters constructor and it is working for me
  • Arnold Vakaria
    Arnold Vakaria over 3 years
    The BinaryFormatter is insecure, take a look on official docs: docs.microsoft.com/en-us/dotnet/api/…
  • Andrea Falappi - Polipo
    Andrea Falappi - Polipo about 3 years
    The private members are not cloned using the JSON method can be avoid using the nuget package PrivateSetterContractResolver
  • Ogglas
    Ogglas about 3 years
    If you vote down please add a comment why, hard to improve answers otherwise.
  • Hakan Usakli
    Hakan Usakli about 3 years
    fastclone worked over 10x faster for me compared to binaryformatter with .NET 4.6.2. Objects cloned are complex types with dictionaries, custom structures, generic lists with nested objects. Everything worked out of the box with no changes to the class.
  • Karolis Vaitkevicius
    Karolis Vaitkevicius about 3 years
    @3Dave I think the .MemberwiseClone() method is deeply undervalued in this post. It is an actual microsoft already existing method which solved my problems. Thank you.
  • Desolator
    Desolator about 3 years
    change "self" to "source" also this fails if we have a child list that contains a reference to the main object. It'll get an infinite loop. You need to add "ReferenceLoopHandling = ReferenceLoopHandling.Ignore" to the settings of both Serialize and Deserialize methods.
  • Meer
    Meer almost 3 years
    Nice package, I started using it today. Just one thing I noticed, the namespace and class name are same, so to use the static method of class ObjectCloner, I have to explicitly come from the namespace despite using the directive, as for example - ObjectCloner.ObjectCloner.DeepClone(someObject).
  • Kiquenet
    Kiquenet almost 3 years
    What is self ?
  • Kiquenet
    Kiquenet almost 3 years
    Valid for Deep clone ?
  • Kiquenet
    Kiquenet almost 3 years
    extends Person in C# ?
  • alelom
    alelom almost 3 years
    @SalathielGenèse Me too. See if this helps: stackoverflow.com/a/56933017/3873799
  • alelom
    alelom almost 3 years
    There is an excellent Nuget package that manages Cloning as C#, in my opinion, should. See stackoverflow.com/a/56933017/3873799
  • Mark Nadig
    Mark Nadig over 2 years
    Based on what I've read, this is only for the new "record" type. One of us should really just try this out in .net fiddle :P
  • Izzy
    Izzy over 2 years
    @MarkNadig I hadn't even noticed that! It looks like using a record to clone a class doesn't work- dotnetfiddle.net/w3IJgG; But Cloning for a flat record does appear to copy by value! dotnetfiddle.net/MCHGEL
  • Tony
    Tony over 2 years
    With AnyClone I just installed the NuGet Package, called .Clone() and it worked very well on a Blazor project here!
  • Christopher
    Christopher over 2 years
    So far this is working for my situation. Thank you.
  • Andrew
    Andrew over 2 years
    Two issues - first there's no automatic constructor in c# that will take an object of the same type so new MyObject(myObj); will probably error. Second if you created such a constructor, it would either be a shallow clone or you'd have to use similar constructors every step into properties of the object to clone contained objects and collection.
  • Andrew
    Andrew over 2 years
    The author asked for a deep clone so they could "make changes to the new object that are not reflected in the original object." This answer creates a shallow clone where any changes to objects within the clone will change the original.
  • Alexandru Dicu
    Alexandru Dicu over 2 years
    An extra package reference for cloning an object ? Not so nice.
  • alelom
    alelom over 2 years
    Feel free to implement one of the million solutions proposed in this thread then. I find this package to be a very convenient solution. I only wish MS would embed a solution equivalent to this in C# or .NET.
  • August
    August over 2 years
    Important note about BinaryFormatter deprecation mentioned here
  • Aaron Haspel
    Aaron Haspel about 2 years
    I used to do custom cloning, like the original questioner, but this package, unlike the various serialization/deserialization solutions, is every bit as fast and worked perfectly out of the box. I don't like the extra package reference either, but for me it was more than worth it.
  • RBZ
    RBZ almost 2 years
    "BinaryFormatter serialization methods are obsolete and prohibited in ASP.NET apps". Recommended action Stop using BinaryFormatter in your code. Instead, consider using JsonSerializer or XmlSerializer. The main reason is security related: docs.microsoft.com/en-us/dotnet/standard/serialization/…
  • RBZ
    RBZ almost 2 years
    "BinaryFormatter serialization methods are obsolete and prohibited in ASP.NET apps". Recommended action Stop using BinaryFormatter in your code. Instead, consider using JsonSerializer or XmlSerializer. The main reason is security related: docs.microsoft.com/en-us/dotnet/standard/serialization/…