I pass a two-dimensional array as a property to my user control. There I store this values in another two-dimensional array:
int[,] originalValues = this.Met
IClonable is great but unless you IClonable
every type in your top level cloned type, you end up with references, AFAIK.
Based on that, unless you want to walk the object and clone each object within, this seems the simplest approach.
It's simple and guarantees a clean break from references of deep objects in the original:
using Newtonsoft.Json;
private T DeepCopy<T>(object input) where T : class
{
var copy = JsonConvert.SerializeObject((T)input); // serialise to string json object
var output = JsonConvert.DeserializeObject<T>(copy); // deserialise back to poco
return output;
}
Usage:
var x = DeepCopy<{ComplexType}>(itemToBeCloned);
Where ComplexType
is anything wanting a break from references.
It takes any Type in, stringifies it, then de-stringifies to a new copy.
Best use example: If you've selected a complex type as a result of a lambda query and want to modify the result without affecting the original.
You need to create a new array. You then need to manually copy the value of each element into the new array. What you are doing in the example given is to create two array variables which both reference the same array.
The problem with the clone method is that it is a shallow copy. In this isntance, because you are using int
, it does not mater. Howver, if you had an array of classes the definition of the ICLonable interface leaves it ambiguous as to how deep the clone will go.
Imagine if you had a class that has properties that are other classes which has properties that are other classes. The clonable interface does not state whether it will also clone the sub members or not. Moreover, many people have different views on what the expected behaviour is.
Hence this is why it is often recommended to define two interfaces, IShallowCopy
and IDeepCopy
.
Here is a fast solution that is almost similar than some answers here, but which mention MemberwiseClone.
I have POCO classes that only contains reference values.
public class MyPoco {
public int x { get; set; }
public int y { get; set; }
public int z { get; set; }
// Add a "Clone" method.
public MyPoco Clone() {
return (MyPoco)this.MemberwiseClone();
}
}
Then use LINQ to build a new array of clones:
var myClone = MyPocoArray.Select(x => x.Clone).ToArray();