How to clone a <T> collection?

I have an enumeration, Fruit and the FruitCollection class that outputs a Collection<Fruit> . I could not find a way to clone FruitCollection using .NET, and I found this MSDN article that defined the DeepClone() function and used MemberwiseClone() . Now, since this is an enumeration, I don’t think I need to "deeply" clone it, so I thought MemberwiseClone() would be sufficient. However, when I try to use it in PowerShell, the cloned object seems to be just a pointer to the source object, not the clown. What am I doing wrong?

Is there any other way to just clone a Collection ? FruitCollection has no other custom elements.

C # code:

 public enum Fruit { Apple = 1, Orange = 2 } public class FruitCollection : Collection<Fruit> { public FruitCollection Clone() { return Clone(this); } public static FruitCollection Clone(FruitCollection fruitCollection) { return (FruitCollection)fruitCollection.MemberwiseClone(); } } 

PowerShell Output:

 PS> $basket1 = New-Object TestLibrary.FruitCollection PS> $basket1.Add([TestLibrary.Fruit]::Apple) PS> $basket2 = $basket1.Clone() PS> $basket1.Add([TestLibrary.Fruit]::Orange) PS> $basket2 Apple Orange 
+5
source share
3 answers

As other commentators noted, you can use the constructor that already exists in the collection, and then in your Clone , create a new list for the new collection, so adding to basket1 does not affect basket2, etc.

 public class FruitCollection : Collection<Fruit> { public FruitCollection(IList<Fruit> source) : base(source) { } public FruitCollection() { } public FruitCollection Clone() { return Clone(this); } public static FruitCollection Clone(FruitCollection fruitCollection) { // ToList() will give a new List. Otherwise Collection will use the same IList we passed. return new FruitCollection(fruitCollection.ToList()); } } void Main() { var basket1 = new FruitCollection(); basket1.Add(Fruit.Apple); var basket2 = basket1.Clone(); basket2.Add(Fruit.Orange); Console.WriteLine("{0}", basket1.Count); Console.WriteLine("{0}", basket2.Count); } 
+4
source

This is because you are doing a photocopy of a member, which is a shallow copy of the non-static fields of the object. Since your object is a Collection (reference type), it copies only the reference to the collection.

Try this instead:

 public class FruitCollection : Collection<Fruit> { public FruitCollection Clone() { return Clone(this); } public static FruitCollection Clone(FruitCollection fruitCollection) { var clonedFruitCollection = new FruitCollection(); // Deep copy the collection instead of copying the reference with MemberwiseClone() foreach (var fruit in fruitCollection) { clonedFruitCollection.Add(fruit); } return clonedFruitCollection; } } 
+2
source

Create a new FruitCollection and add all the elements to it. You can also create a constructor that does this, see this http://msdn.microsoft.com/en-us/library/fkbw11z0%28v=vs.110%29.aspx .

+1
source

Source: https://habr.com/ru/post/1203734/


All Articles