views:

48

answers:

3

Okay, I have what I think is a simple question.. or just a case of me being a C# beginner.

I have an array of custom objects (clsScriptItem) that I am populating from a database. Once the items are loaded, I want to back them up to "backup" array so I can revert the information back after changing the main array. However, when I use CopyTo to copy the array and then alter the original array, the backup array is also being altered... I thought CopyTo merely copied values + structure from one array to another.

    private void backupItems()
    {
        //lastSavedItems and items are both of type clsScriptItem[] 
        //(declaration not shown)

        lastSavedItems = new clsScriptItem[items.Length];

        items.CopyTo(lastSavedItems, 0);

        //items[0].nexts[0] is 2
        //lastSavedItems[0].nexts[0] is 2

        items[0].nexts[0] = "-1";

        //items[0].nexts[0] is -1
        //lastSavedItems[0].nexts[0] is also -1


    }

How do I backup this data without having the two arrays be 'linked'??

UPDATE : I have updated the backup function to this

    private void backupItems()
    {
        lastSavedItems = new clsScriptItem[items.Length];
        for (int i = 0; i < items.Length; i++)
            lastSavedItems[i] = (clsScriptItem)items[i].Clone();

        items[0].nexts[0] = "-1";

    }

And I have update my class thusly....

public class clsScriptItem : ICloneable 
{

    //other declarations...

    object ICloneable.Clone() { return Clone(); }

    public clsScriptItem Clone()
    {
        return ((clsScriptItem)MemberwiseClone());
    }
}

** - and the same thing is happening.. Any thoughts?**

+4  A: 

they aren't linked, you are using references to objects (So the second array contains 'pointers' to elements, which are the same as 'pointers' in first array..) so declare clsScriptItem as struct, or implement ICloneable interface and use

for(int i = 0; i < items.Length; i++)
    lastSavedItems[i] = (clsScriptItem)items[i].Clone();
Yossarian
please see my update above, I have implemented ICloneable and am copying the same way you showed me how - but the same thing is still happening...
Dutchie432
+1  A: 

This is a classic shallow copy vs deep copy problem. When you copy an array of reference types it is merely the references that are copied, not the objects those references point to. So your end result is two arrays that contain references to the same objects.

So when you copy an array that looks like this

Original
 ----
|    |
| 0  |---> Cls
|    | 
 ----
|    |
| 1  |---> Cls
|    |
 ----

You get this

Original             Copy
 ----                ----
|    |              |    |
| 0  |---> Cls <--- |  0 | 
|    |              |    |
 ----                ----
|    |              |    |
| 1  |---> Cls <--- |  1 |
|    |              |    |              
 ----                ----

If you change the referenced object in any way and it will look like you've changed the contents of both arrays when really all you've done is change the single object pointed to by both arrays.

Jason Punyon
+2  A: 
try this:-

public static MyType[] DeepClone(MyType[] obj)
     {
                using (MemoryStream ms = new MemoryStream())
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(ms, obj);
                    ms.Position = 0;

                    return (MyType[])formatter.Deserialize(ms);
                }
      }
Vinay Pandey
A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
Dutchie432
Type 'tdScriptEditor.clsScriptItem' in Assembly 'tdScriptEditor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
Dutchie432
add [Serializable] before clsScriptItem
Yossarian
Perfect. You're my hero of the day!!
Dutchie432