C # Object Array CopyTo связывает значения обоих массивов? - PullRequest
0 голосов
/ 05 мая 2010

Хорошо, у меня есть вопрос, который я считаю простым ... или случай, когда я начинающий в C #.

У меня есть массив пользовательских объектов (clsScriptItem), которые я заполняю из базы данных. После того, как элементы загружены, я хочу создать их резервную копию в массиве «backup», чтобы я мог вернуть информацию обратно после изменения основного массива. Однако когда я использую CopyTo для копирования массива, а затем изменяю исходный массив, резервный массив также изменяется ... Я думал, что CopyTo просто копирует значения + структуру из одного массива в другой.

    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


    }

Как сделать резервную копию этих данных, не связывая два массива ??

ОБНОВЛЕНИЕ: Я обновил функцию резервного копирования до этого

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

    }

И я обновил свой класс таким образом ....

public class clsScriptItem : ICloneable 
{

    //other declarations...

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

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

** - и то же самое происходит .. Есть мысли? **

Ответы [ 3 ]

4 голосов
/ 05 мая 2010

они не связаны, вы используете ссылки на объекты (поэтому второй массив содержит «указатели» на элементы, которые совпадают с «указателями» в первом массиве ...), поэтому объявите clsScriptItem как struct, или реализовать ICloneable интерфейс и использовать

for(int i = 0; i < items.Length; i++)
    lastSavedItems[i] = (clsScriptItem)items[i].Clone();
3 голосов
/ 05 мая 2010
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);
                }
      }
1 голос
/ 05 мая 2010

Это классическая мелкая копия против проблемы глубокой копии. При копировании массива ссылочных типов копируются только ссылки, а не объекты, на которые указывают эти ссылки. Таким образом, ваш конечный результат - два массива, которые содержат ссылки на одни и те же объекты.

Итак, когда вы копируете массив, который выглядит следующим образом

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

Вы получите это

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

Если вы каким-либо образом измените ссылочный объект, и будет выглядеть, как будто вы изменили содержимое обоих массивов, когда на самом деле все, что вы сделали, - это изменили единственный объект, на который указывают оба массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...