如何克隆Collection <t>?</t>

时间:2014-09-30 17:27:33

标签: c# powershell collections clone

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

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

C#代码:

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输出:

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

3 个答案:

答案 0 :(得分:4)

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

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);
}

答案 1 :(得分:2)

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

请改为尝试:

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 :(得分:1)

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