【问题标题】:Array.Clone() (Copy or not?)Array.Clone() (是否复制?)
【发布时间】:2014-02-27 11:04:49
【问题描述】:

我怀疑我只是误解了 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

所以我在克隆上的操作似乎也反映在克隆的源中,这对我来说意味着它没有复制对象它复制了指向对象的指针,并且破坏了克隆方法开始的目的与..??

【问题讨论】:

  • 这与 shallow 正好相反。被复制的只是数组本身
  • 浅拷贝意味着它正在复制指针而不是创建新对象。
  • 好的,我可以接受,MSDN 声明“数组的浅拷贝只复制数组的元素,无论它们是引用类型还是值类型,但它不会复制引用引用。新数组中的引用指向的对象与原始数组中的引用指向的对象相同。这似乎也支持这一点。那么我怎么才能得到不引用原件的副本呢?

标签: c# arrays clone


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    浅拷贝 意味着你得到了新的数组,但是数组中的值被照原样复制。对于引用类型(作为您的类),这意味着引用被复制,因此您的新数组指向您的类的相同实例。

    如果你想执行深拷贝,你必须自己做:

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

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

    【讨论】:

    • 好的,这是有道理的,尽管我知道这必须在某种程度上发生才能起作用,但我会认为它会出现在数组类的原始设计中。
    猜你喜欢
    • 2013-05-14
    • 1970-01-01
    • 2018-02-26
    • 2016-07-30
    • 2011-07-10
    • 2016-02-18
    • 2016-01-28
    • 2019-04-13
    • 2014-03-28
    相关资源
    最近更新 更多