Array.Clone()(复制与否?)

时间:2014-02-03 19:40:10

标签: c# arrays clone

我怀疑我只是误解了Array类的Clone()方法。 但它会读取“创建System.Array的浅拷贝”,所以我认为这意味着新的对象指针,而不是相同的对象指针......

以下是否真的应该发生?

假设一个测试对象......

public class testObject 
{
    public int propInt { get; set; }
}

以及以下测试...

//create a the list
List<testObject> testList = new List<testObject>();

//add items to the list
testObject item1 = new testObject();
item1.propInt = 1;
testList.Add(item1);

testObject item2 = new testObject();
item2.propInt = 2;
testList.Add(item2);

//create what should be a COPY of the array
testObject[] testArray;
testArray = (testObject[])testList.ToArray().Clone();


foreach (testObject item in testArray)
{
    item.propInt++;
}

//check items in list
foreach (testObject item in testList)
{
    Trace.WriteLine("List:" + item.propInt);
}

//check items in coppied array
foreach (testObject item in testArray)
{
    Trace.WriteLine("Array:" + item.propInt);
}

我希望结果是......

List:1
List:2

Array:2
Array:3

因为我假设我做了一个克隆,所以该克隆中的引用将是一个具有与制作克隆时相同属性的相同对象类型的新实例。此外,我会在修改它们之后假设原始列表未受影响。

没有快乐,这个测试的输出实际上是......

List:2
List:3

Array:2
Array:3

所以我对Clone的操作似乎也反映在克隆的源代码中,这对我来说意味着它没有复制它将指针复制到对象的对象,并且无法开始克隆方法的目的与..?

2 个答案:

答案 0 :(得分:5)

浅拷贝表示您获得了新数组,但数组中的值将按原样复制。对于引用类型(作为您的类),它意味着复制引用,因此您的新数组指向类的相同实例。

如果您想要执行深层复制,您必须自己动手:

var copy = source.Select(x => new testObject() { propInt = x.propInt }).ToArray();

或使用克隆库(例如CloneExtensions)。

答案 1 :(得分:1)

Clone()方法仅用于复制Array对象,而不是其中的引用。如果要复制对象,则必须为所需的Collection创建子类并覆盖Clone()方法。但是,Clone()方法通常来自ICloneable接口。如果是Interface的实现,则必须检查包含的对象。我会建议这样的事情:

public class ClonableList<T> : List<T>, ICloneable
    where T : ICloneable
{
    public object Clone()
    {
        ClonableList<T> newList = new ClonableList<T>();

        foreach (T item in this)
        {
            newList.Add((T)item.Clone());
        }

        return newList;
    }
}