需要有关克隆包含可克隆对象的数组的说明

时间:2014-05-28 08:43:45

标签: c# clone cloneable

我正在尝试以下代码:

public class cloneTest : ICloneable {

    public string strValue { get; set; }

    public object Clone( ) {
      cloneTest n = new cloneTest( );
      n.strValue = this.strValue;
      return n;     
    }
}

cloneTest obj1 = new cloneTest( ) { strValue = "one" };
cloneTest obj2 = new cloneTest( ) { strValue = "two" };
cloneTest obj3 = new cloneTest( ) { strValue = "three" };

cloneTest[ ] strValueArray = new cloneTest[  ] {obj1, obj2, obj3};

cloneTest[ ] strValueArrayClone = ( cloneTest[ ] )strValueArray.Clone( );
strValueArrayClone[ 2 ].strValue = "four";

当我修改我的代码中指定的strValuArrayClone对象时,此更改也反映在strValueArray对象中,即使我正在创建克隆。但是,如果尝试下面的代码,那么一切都很顺利。我想了解它背后的逻辑。

cloneTest obj1 = new cloneTest( ) { strValue = "one" };
cloneTest obj2 = new cloneTest( ) { strValue = "two" };
cloneTest obj3 = new cloneTest( ) { strValue = "three" };

cloneTest[ ] strValueArray = new cloneTest[  ] {obj1, obj2, obj3};

cloneTest[ ] strValueArrayClone = ( cloneTest[ ] )strValueArray.Clone( );
cloneTest obj2clone = ( cloneTest )obj2.Clone( );
obj2clone.strValue = "six";
strValueArrayClone[ 2 ] = obj2clone;

1 个答案:

答案 0 :(得分:2)

您正在创建数组的 ,但内容相同。数组Clone()方法是浅层克隆。由于内容是 references ,因此两个数组中的插槽都指向相同的实际对象实例。在第一个代码示例中,无论您使用对这3个实例的引用创建了多少个数组,都只有3个cloneTest个实例。如果你在这3个对象中的一个上更改了一个属性,它将在任何引用该对象的地方都可见 - 这意味着通过每个数组。

选项:

  • 创建深层克隆(即克隆内部项目,克隆阵列时)
  • 在更改属性时克隆对象(这是您的第二个代码示例所执行的操作)
    • 一个特殊情况是使原始类型不可变,以排除此类事件