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
If you want to deep copy an array of reference types, you can do this methodology:
Implement IClonable
iterface for your class and do your deep copy of all value typed fields inside to another constructed object.
class A: ICloneable {
int field1;
public object Clone()
{
A a= new A();
//copy your fields here
a.field1 = this.field1;
...
}
}
Then you can do the actual copy using
A[] array1 = new A[]{....};
A[] array2 = array1.Select(a => a.Clone()).ToList();
You can deepcopy a 1d array using LINQ.
var array = Enumerable.Range(0, 10).ToArray();
var array2 = array.Select(x => x).ToArray();
array2[0] = 5;
Console.WriteLine(array[0]); // 0
Console.WriteLine(array2[0]); // 5
With 2d array, this will not work because 2d array doesn't implement IEnumerable.
The crux of your problem is here:
There I store this values in another two-dimensional array
This is actually inaccurate. You are not creating a new array; you are setting your originalValues
variable to the same array. For a more detailed explanation, see below.
The confusion expressed in the comments to Pieter's answer is due to some uncertainty surrounding the term "deep copy."
When it comes to copying objects, there's deep copying and shallow copying.
Deep copying involves making a copy of all the data belonging to an object, which means that if the object includes members which are themselves complex (for example, instances of user-defined reference types), those objects must be deep-copied as well (along with all of their members, and so on).
Shallow copying involves simply copying all of the fields from one object to another, which means that if the object includes reference types, only the references need to be copied (and so the copied references will be pointing to the same objects).
In the case of the code you've posted:
int[,] originalValues = this.Metrics;
... there's actually no copying of any objects at all. All you've done is copied a single reference, assigning the value of this.Metrics
(a reference) to the variable originalValues
(also a reference, to the very same array). This is essentially the same as a simple value assignment, like this:
int x = y; // No objects being copied here.
Now, the Array.Clone
method makes, in fact, a shallow copy. But as Pieter pointed out, there's really no difference between a "shallow" or "deep" copy of an array of integers, since integers are not complex objects.
If you had something like this:
StringBuilder[,] builders = GetStringBuilders();
StringBuilder[,] builderCopies = (StringBuilder[,])builders.Clone();
..., you'd end up with a whole new array (a copy, yes), but one containing all of the same StringBuilder
objects (so a shallow copy). This is where deep versus shallow copying comes into play; if you wanted a new array containing copies of all of the StringBuilder
objects from builders
, you'd need to make a deep copy.
You can clone an array, which makes a copy of it:
int[,] originalValues = (int[,])this.Metrics.Clone();
I don't know where I got this from, but this works well for me.
public static class GenericCopier<T> //deep copy a list
{
public static T DeepCopy(object objectToCopy)
{
using (MemoryStream memoryStream = new MemoryStream())
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, objectToCopy);
memoryStream.Seek(0, SeekOrigin.Begin);
return (T)binaryFormatter.Deserialize(memoryStream);
}
}
}
If the object you are copying is an array, then you can use:
Array.Copy(sourceArray, destinationArray, sourceArray.Count)
This will give you a separate copy of the original array into your destination array.