如何克隆Collection ?

我有一个枚举, Fruit和一个类FruitCollection ,它派生Collection 。 我找不到使用.NET克隆FruitCollection方法,我发现这篇MSDN文章定义了一个DeepClone()函数并使用了MemberwiseClone() 。 现在,因为这是一个枚举,我认为我不需要“深入”克隆它,所以我认为MemberwiseClone()就足够了。 但是,当我在PowerShell中尝试它时,克隆的对象似乎只是指向原始对象而不是克隆的指针。 我究竟做错了什么?

还有另一种简单克隆Collection吗? FruitCollection没有其他自定义成员。

C#代码:

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

PowerShell输出:

 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 

正如其他人在评论中指出的那样,你可以使用已经存在于Collection上的构造函数,然后在你的Clone中创建一个新的列表供新的Collection使用,这样添加到basket1不会影响basket2等等。

 public class FruitCollection : Collection { public FruitCollection(IList 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); } 

这是因为您正在执行Memberwise克隆,它是对象的非静态字段的浅表副本。 由于您的对象是Collection(引用类型),因此它只复制对该集合的引用。

试试这个:

 public class FruitCollection : Collection { 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; } } 

创建一个新的FruitCollection并向其添加所有元素。 您还可以创建一个构造函数来执行此操作,请参阅此http://msdn.microsoft.com/en-us/library/fkbw11z0%28v=vs.110%29.aspx 。