Deep cloning objects
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:
- Manually with ICloneable, which is Shallow and not Type-Safe
- MemberwiseClone, which uses ICloneable
- Reflection by using Activator.CreateInstance and recursive MemberwiseClone
- Serialization, as pointed by johnc's preferred answer
- Intermediate Language, which I got no idea how works
- Extension Methods, such as this custom clone framework by Havard Straden
- Expression Trees
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.
NakedBrunch
C#/VB .NET web Developer with a focus on dynamic communication solutions.
Updated on April 14, 2022Comments
-
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 over 12 yearsMay be useful: "Why Copying an Object is a terrible thing to do?" agiledeveloper.com/articles/cloning072002.htm
-
Felix K. about 12 yearsstackoverflow.com/questions/8025890/… Another solution...
-
Daniel Little over 11 yearsYou should have a look at AutoMapper
-
Pedro77 almost 11 yearsYour solution is far more complex, I got lost reading it... hehehe. I'm using an DeepClone interface. public interface IDeepCloneable<T> { T DeepClone(); }
-
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 aList<T>
depends not just uponT
, 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 almost 10 yearsThis question is also answered here stackoverflow.com/q/129389/235715
-
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 passedthis
. So copying is turrible [sic], but copying carefully (and the article's definitely worth reading) isn't. ;^) -
Mertuarez about 8 yearsIf you need this perhaps you have wrong implementation. And if you use dependency injection it does not make sense at all.
-
C Perkins about 7 yearsIn 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 over 6 yearsWhy 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 over 6 yearsCall 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 over 5 yearsCheck this Answer: stackoverflow.com/a/52097307/4707576 about: Cloning objects without Serialization
-
-
Karg over 15 yearsICloneable doesn't have a generic interface, so it is not recommended to use that interface.
-
Karg over 15 yearsICloneable doesn't have a generic interface, so it is not recommended to use that interface.
-
Pop Catalin over 15 years.Net doesn't have copy constructors.
-
Pop Catalin over 15 yearsYour 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 over 15 yearsSure it does: new MyObject(objToCloneFrom) Just declare a ctor which takes the object to clone as a parameter.
-
Raymond over 15 yearsstackoverflow.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 almost 15 yearsIt'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 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 over 14 yearsSerialization/deserialization involves significant overhead that isn't necessary. See the ICloneable interface and .MemberWise() clone methods in C#.
-
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 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 over 13 yearsI'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 over 13 yearsI'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 over 13 yearsYour 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 over 13 yearsInstead of "if (!typeof(T).IsSerializable)" you can write "public static T Clone<T>(T source) where T : ISerializable
-
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 theISerializable
interface. -
Jerry Nixon almost 13 yearsI recommend this method signature: public static T Copy<T>(this T item) where T: ISerializable
-
epalm almost 13 yearsAs mentioned here you'll have to mark unserializable private fields/events as
[NonSerialized]
(or[field: NonSerialized]
) for this to work. -
johnc almost 13 years@epalm, certainly a passable knowledge of Serialization is required, but it's a fairly easy learning curve
-
Alex Norcliffe over 12 yearsJust 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 over 12 yearsThis, 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 over 12 yearsThis looks like memberwise clone because does not aware of reference type properties
-
Will over 12 yearsWith copy constructors you lose hierarchy though. agiledeveloper.com/articles/cloning072002.htm
-
Contango over 12 yearsIf 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 over 12 yearsI like the copy constructor; but suppose you have an
AbstractBaseType
, with 3 derived types, each nested such thatType1:AbstractBaseType
has aType2:AbstractBaseType
member, which has aType3:AbstractBaseType
member. Now you have to check the types. -
Felix K. about 12 yearsstackoverflow.com/questions/8025890/… My solution.
-
Konstantin Salavatov about 12 yearsto Alex Norcliffe : author of question asked about "copying each property" rather then cloning. in most cases exact duplication of properties is not needed.
-
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 over 11 yearsJohnc, 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 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 over 11 years@RubenBartelink and how about my brand new answer? :P
-
Koryu almost 11 yearsi 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. over 10 years@IAbstract : Why should you have to check the types? Just rely on inheritance: pastebin.com/XWGQFBhr ...
-
IAbstract over 10 yearsDescendants 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. 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 about 10 yearsthe solutiojn is even faster than the BinaryFormatter solution, .NET Serialization Performance Comparison
-
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 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 almost 10 yearsThe 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 almost 10 yearsWhat are the chances of this getting on NuGet? It seems like the best solution. How does it compare to NClone?
-
Mark Ewer almost 10 yearsThanks for this. I was able to do essentially the same thing with the BSON serializer that ships with the MongoDB driver for C#.
-
odyth over 9 yearsMemberwiseClone method creates a shallow copy NOT a deep copy. msdn.microsoft.com/en-us/library/…
-
BateTech over 9 yearsMS 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 over 9 yearsFirst 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 over 9 yearsThis is the best way for me, However, I use
Newtonsoft.Json.JsonConvert
but it is the same -
LuckyLikey about 9 yearsThis one seems to be pretty useful
-
TarmoPikaro about 9 yearsIt'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 almost 9 yearsIf you copy a struct you get a shallow copy, you might still need specific implementation for a deep copy.
-
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 almost 9 yearsThe 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 almost 9 yearsI 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 almost 9 yearsI'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 over 8 yearsUsing a constructor means Copy/Clone cannot be part of an interface
-
MonsterMMORPG over 8 yearsCreateInstanceOfType is not defined?
-
Roma Borodov over 8 yearsNot at all, you wrong about reflection, you should simply cache this properly. Check my answer below stackoverflow.com/a/34368738/4711853
-
Mr.B almost 8 yearsIt fails on interger: "Non-static method requires a target."
-
Toxantron almost 8 yearsYou can use the CGbR Clone Generator and get a similar result without manually writing the code.
-
Simon Tewsi almost 8 yearsTried 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 almost 8 yearsThis does not work when your object is an interface.
-
Tseng over 7 yearsCalling
prop.GetValue(...)
is still reflection and can't be cached. In an expression tree its compiled though, so faster -
Anya Hope over 7 yearsCan 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 about 7 yearsBe 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. about 7 yearsA 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 over 6 yearscloning 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 over 6 yearsThe answer from the duplicate stackoverflow.com/questions/129389/… describes Copy extension, based on recursive MembershipClone
-
Michael Freidgeim over 6 yearsIntermediate Language implementation is useful
-
radomeit about 6 yearsFor 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 about 6 yearsSimple and concise answers are the best.
-
Konrad over 5 yearsThere's no final in C#
-
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 over 5 yearsI tried it and it didn't work at all for me. Throws a MemberAccess exception.
-
Michael Sander over 5 yearsIt doesn't work with newer versions of .NET and is discontinued
-
Artemious over 5 yearsThanks for the different approaches performance comparison from the article codeproject.com/Articles/1111658/…
-
mr5 over 5 yearsI think this is the best solution as the implementation can be applied on most programming languages.
-
N73k almost 5 yearsThis only does a shallow copy.
-
N73k almost 5 yearsExpressionTree implementation seems very good. It even works with circular references and private members. No attributes needed. Best answer I've found.
-
Ted Mucuzany almost 5 yearsIt really is. It can cause tricky side-effects, so it should be use carefully.
-
marbel82 almost 5 yearsIn DeserializeObject() you should add additional options
new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace}
, because default constructor can change something that's not in the source 🔗 -
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 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 over 4 yearsThe best answer, worked very well, you saved my day
-
EduLopez almost 4 yearsThis question is quite old. I think this answer should go up so people can actually see the value here.
-
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 almost 4 yearsThe 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 over 3 yearsI'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 over 3 yearsI used NewtonSoft's 12.0.3 version, my class's hasn't parameters constructor and it is working for me
-
Arnold Vakaria over 3 yearsThe BinaryFormatter is insecure, take a look on official docs: docs.microsoft.com/en-us/dotnet/api/…
-
Andrea Falappi - Polipo about 3 yearsThe private members are not cloned using the JSON method can be avoid using the nuget package PrivateSetterContractResolver
-
Ogglas about 3 yearsIf you vote down please add a comment why, hard to improve answers otherwise.
-
Hakan Usakli about 3 yearsfastclone 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 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 about 3 yearschange "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 almost 3 yearsNice 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 almost 3 yearsWhat is self ?
-
Kiquenet almost 3 yearsValid for Deep clone ?
-
Kiquenet almost 3 years
extends Person
in C# ? -
alelom almost 3 years@SalathielGenèse Me too. See if this helps: stackoverflow.com/a/56933017/3873799
-
alelom almost 3 yearsThere is an excellent Nuget package that manages Cloning as C#, in my opinion, should. See stackoverflow.com/a/56933017/3873799
-
Mark Nadig over 2 yearsBased 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 over 2 years@MarkNadig I hadn't even noticed that! It looks like using a
record
to clone aclass
doesn't work- dotnetfiddle.net/w3IJgG; But Cloning for a flatrecord
does appear to copy by value! dotnetfiddle.net/MCHGEL -
Tony over 2 yearsWith
AnyClone
I just installed the NuGet Package, called .Clone() and it worked very well on a Blazor project here! -
Christopher over 2 yearsSo far this is working for my situation. Thank you.
-
Andrew over 2 yearsTwo 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 over 2 yearsThe 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 over 2 yearsAn extra package reference for cloning an object ? Not so nice.
-
alelom over 2 yearsFeel 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 over 2 yearsImportant note about BinaryFormatter deprecation mentioned here
-
Aaron Haspel about 2 yearsI 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 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 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/…