I thought that to clone a List you would just call:
List<int> cloneList = new List<int>(originalList);
But I tried that in my code and I seem to be getting effects that imply the above is simply doing:
cloneList = originalList... because changes to cloneList seem to be affecting originalList.
So what is the way to clone a List?
EDIT:
I am thinking of doing something like this:
public static List<T> Clone<T>(this List<T> originalList) where T : ICloneable { return originalList.ConvertAll(x => (T) x.Clone()); }
EDIT2:
I took the deep copy code suggested by Binoj Antony and created this extension method:
public static T DeepCopy<T>(this T original) where T : class { using (MemoryStream memoryStream = new MemoryStream()) { BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(memoryStream, original); memoryStream.Seek(0, SeekOrigin.Begin); return (T)binaryFormatter.Deserialize(memoryStream); } }
EDIT3:
Now, say the items in the List are structs. What then would result if I called?:
List<StructType> cloneList = new List<StructType>(originalList);
I am pretty sure than I would get a List filled with new unique items, correct?
To clone a list, one can iterate through the original list and use the clone method to copy all the list elements and use the add method to append them to the list. Approach: Create a cloneable class, which has the clone method overridden. Create a list of the class objects from an array using the asList method.
To add the contents of one list to another list which already exists, you can use: targetList. AddRange(sourceList); If you're just wanting to create a new copy of the list, see the top answer.
This would work...
List<Foo> cloneList = new List<Foo>(originalList);
When you say "because changes to cloneList seem to be affecting originalList." - do you mean changes to the list, or changes to the items...
Adding / removing / swapping items is changing the list - so if we do:
cloneList.Add(anotherItem);
you should find that cloneList
is longer than originalList
. However, if the contents are reference-types (classes), then both lists are still pointing at the same underlying objects - so if we do:
cloneList[0].SomeObjectProperty = 12345;
then this will also show against originalList[0].SomeObjectProperty
- there is only a single object (shared between both lists).
If this is the problem, you will have to clone the objects in the list - and then you get into the whole deep vs shallow issue... is this the problem?
For a shallow copy, you might be able to use something very much like the answer here - simply with TTo = TFrom
(perhaps simplify to a single T
).
You can use the below code to make a deep copy of the list or any other object supporting serialization:
Also you can use this for any version of .NET framework from v 2.0 and above, and the similar technique can be applied (removing the usage of generics) and used in 1.1 as well
public static class GenericCopier<T> { 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); } } }
You can call it by using
List<int> deepCopiedList = GenericCopier<List<int>>.DeepCopy(originalList);
Full code to test if this works:
static void Main(string[] args) { List<int> originalList = new List<int>(5); Random random = new Random(); for(int i = 0; i < 5; i++) { originalList.Add(random.Next(1, 100)); Console.WriteLine("List[{0}] = {1}", i, originalList[i]); } List<int> deepCopiedList = GenericCopier<List<int>>.DeepCopy(originalList); for (int i = 0; i < 5; i++) Console.WriteLine("deepCopiedList[{0}] value is {1}", i, deepCopiedList[i]); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With