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?
Whilst the standard practice 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 in our stuff.As mentioned elsewhere, it does require your objects to be serializable.
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.
And with the use of extension methods (also from the originally referenced source):
In case you prefer to use the new extension methods of C# 3.0, change the method to have the following signature:
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)
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 ofMemberwiseClone
isn'tClone
; 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.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.
Also, you can use this extension method
Here is a deep copy implementation:
Follow these steps:
ISelf<T>
with a read-onlySelf
property that returnsT
, andICloneable<out T>
, which derives fromISelf<T>
and includes a methodT Clone()
.CloneBase
type which implements aprotected virtual generic VirtualClone
castingMemberwiseClone
to the passed-in type.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 typeICloneable<theNonCloneableType>
. This will allow a routine that expects a cloneable derivative ofFoo
to work with a cloneable derivative ofDerivedFoo
, but also allow the creation of non-cloneable derivatives ofFoo
.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;