1

我正在尝试以下代码:

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

1 回答 1

2

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

选项:

  • 创建一个深度克隆(即在克隆数组时也克隆内部项目)
  • 在更改属性时克隆对象(这是您的第二个代码示例所做的)
    • 这种情况的一个特例是使原始类型不可变,以排除这种情况
于 2014-05-28T08:51:46.933 回答