1

I am trying following code:

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

When I modify the strValuArrayClone object as specified in my code, this change also reflects in strValueArray object even though, I am creating clone. However if try below code, then everything work smoothly. I want to understand the logic behind it.

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;
User1551892
  • 3,236
  • 8
  • 32
  • 52

1 Answers1

2

You are creating a clone of the array, but with the same contents. The array Clone() method is a shallow clone. Since the contents are references, the slots in both arrays refer to the same actual objects instances. In the first code sample, there are only 3 cloneTest instances no matter how many arrays you create with references to those 3 instances. If you change a property on one of those 3 objects, it will be visible everywhere that has a reference to that object - which means via every array.

Options:

  • create a deep clone (i.e. clone the internal items too, at the point of cloning the array)
  • clone objects at the point of changing properties (this is what your second code sample does)
    • a special-case of this is to make the original types immutable, to preclude such occurrences
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks for explanation. I want to understand, what benefit, one can get with shallow clone? – User1551892 May 28 '14 at 08:59
  • 1
    @User1551892 it gives you an isolated snapshot of the array - before you start swapping references, etc. Note that for value-types, this will be a true clone of their internal values etc, but it is almost always (i.e. > 99% of the time) desirable to make structs immutable *anyway*. – Marc Gravell May 28 '14 at 09:16