You can try googling for "deep copy vs shallow copy". You can also look for articles on "reference types vs value types", it will help you understand what's going on with your data.
The difference is:
- If you want to copy the entire data, so that changes to the copy are not reflected in your original instance, then you want a deep copy. This means .NET will need to allocate as much memory as for the original object, and all objects which are pointer by your object will also be copied.
- If you are just displaying your data, or you don't care if you are working with the same instance of you data in two places, then you can use a shallow copy, or you can simply use a reference to your first object.
No copying is done if you are using a reference - you only have a single object in memory. If you are using a shallow copy, then you are making a new object, but other objects which are pointed by your object are
not copied, so changes to these objects will again reflect in your original object.
Here is an example. Consider you have a class such as this:
- class MyData
-
{
-
private List<int> _list = new List<int>();
-
public IList<int> List
-
{
-
get { return _list; }
-
}
-
-
public MyData GetShallowCopy()
-
{
-
return this.MemberwiseClone() as MyData;
-
}
-
-
public MyData GetDeepCopy()
-
{
-
MyData deepCopy = new MyData();
-
foreach (int item in this.List)
-
deepCopy.List.Add(item);
-
return deepCopy;
-
}
-
-
public override string ToString()
-
{
-
StringBuilder sb = new StringBuilder();
-
foreach (int item in this.List)
-
{
-
sb.Append(item);
-
sb.Append(", ");
-
}
-
if (sb.Length > 2)
-
{
-
sb.Length -= 2;
-
}
-
-
return sb.ToString();
-
}
-
}
MyData is a class which contains a List of ints. It also has two methods, "GetShallowCopy" and "GetDeepCopy". The "ToString" method is overridden to simplify printing the object to the Console.
Note the difference between GetShallowCopy and GetDeepCopy.
Now, if you were to use this class in your program, you would do something like this:
- static void Main(string[] args)
-
{
-
MyData data = new MyData();
-
data.List.Add(1);
-
Console.WriteLine(String.Format("Original array: {0}",data.ToString()));
-
-
// This will just create a reference.
-
// reference points to the same object as data, and therefore
-
// reference.List points to the same object as data.List.
-
MyData reference = data;
-
reference.List.Add(2);
-
Console.WriteLine(String.Format("Original array: {0}\t Reference:\t{1}", data.ToString(), reference.ToString()));
-
-
// This will create a shallow copy.
-
// shallowCopy points to a new object, but
-
// shallowCopy.List still points to the same object as data.List.
-
MyData shallowCopy = data.GetShallowCopy();
-
shallowCopy.List.Add(3);
-
Console.WriteLine(String.Format("Original array: {0}\t Shallow copy: \t{1}", data.ToString(), shallowCopy.ToString()));
-
-
// This will create a deep copy.
-
// deepCopy points to a new object,
-
// and deepCopy.List points to a new object.
-
MyData deepCopy = data.GetDeepCopy();
-
deepCopy.List.Add(4);
-
Console.WriteLine(String.Format("Original array: {0}\t Deep copy: \t{1}", data.ToString(), deepCopy.ToString()));
-
-
Console.ReadLine();
-
}
If you try to run this program, you will notice that any changes to the data in the reference or shallow copy of the original object, are reflected in the original object also. Shallow copy is a new object, but it still points to the same List as the original object. Only the deep copy contains a truly separate list in memory, which can be updated independently.