none
Клонирование массива. RRS feed

  • Вопрос

  • Всем доброго времени суток!=)

    Возникло непонимание при клонирование массива.

    Имеется массив SUM_AGZU, который заполняется внутри for, затем в определенный момент он клонируется, клон для обработки данных, а в сам массив передается ссылка на новый объект. Но по возвращаемому результату, создается впечатление, что при клонирование не создается новый объект с идентичными элементами, а просто передается ссылка, т.к. значения у все строк result равны последнему обрабатываемому.=) Надеюсь не косноязычно объяснил.

    Вот пример код:

    string Parameter_Name = ""; int Object_Count = 0; string Object_Kust = ""; string Object_AGZU = ""; double[] SUM_AGZU = new double[Interval+1]; int Day_Count = 0; double Object_sum = 0; for (int i = 0; i < Data.Count; i++) { if (Parameter_Name != (string)Data[i][0]) { int LastIndex = ((string)Data[i][0]).LastIndexOf("."); string Temp_Node_Name = ((string)Data[i][0]).Substring(0, LastIndex); LumTreeNode TempNode = AddFindNode(Temp_Project_TreeView.Nodes, Temp_Node_Name, "undefined", 0, Temp_Node_Name, false); List<object[]> TempParameters = TempNode.ParameterNode; Parameter_Name = (string)Data[i][0]; if (i != 0) { Object_Count++; } Day_Count = 0; object[] Row_Data = new object[16 + Interval + 1]; string[] Temp_Object = Temp_Node_Name.Split('.'); Row_Data[0] = Temp_Object[1]; Row_Data[1] = Temp_Object[2]; Row_Data[2] = Temp_Object[3]; if (Object_AGZU != ((string)Row_Data[0] + '.' + (string)Row_Data[1])) { if (i != 0) { object[] Row_Data_AGZU = new object[16 + Interval + 1]; double[] Temp_SUM_AGZU; // Клонирование внешнего массива в темповый для обработки и передаем во внешний массив новый объект. Temp_SUM_AGZU = (double[])SUM_AGZU.Clone(); SUM_AGZU = new double[Interval + 1]; string[] Arr_Object_AGZU = Object_AGZU.Split('.'); Row_Data_AGZU[0] = Arr_Object_AGZU[0]; Row_Data_AGZU[14] = Arr_Object_AGZU[1]; for (int k = 0; k < Temp_SUM_AGZU.Length; k++) { Row_Data_AGZU[15 + k + 1] = Temp_SUM_AGZU[k]; } result.Add(Row_Data_AGZU); } Object_AGZU = (string)Row_Data[0] + '.' + (string)Row_Data[1]; } if (Data[i][1] != DBNull.Value) { Object_sum += Double.Parse(Convert.ToString(Data[i][1]).Replace(',', '.'), styles, provider);

    // Присвоение данных элементам основного массива. SUM_AGZU[0] += Double.Parse(Convert.ToString(Data[i][1]).Replace(',', '.'), styles, provider); } result.Add(Row_Data); } else { object[] Row_Data = result[Object_Count]; if (Data[i][1] != DBNull.Value) { Object_sum += Double.Parse(Convert.ToString(Data[i][1]).Replace(',', '.'), styles, provider); Row_Data[16 + Day_Count] = Double.Parse(Convert.ToString(Data[i][1]).Replace(',', '.'), styles, provider);

    // Присвоение данных элементам основного массива. SUM_AGZU[Day_Count] += Double.Parse(Convert.ToString(Data[i][1]).Replace(',', '.'), styles, provider); } else { Row_Data[16 + Day_Count] = null; } Day_Count++; } }

    Может подскажите в чем проблемка?=)




    • Изменено wUI 26 июня 2013 г. 9:45
    • Перемещено YatajgaEditor 26 июня 2013 г. 15:48
    26 июня 2013 г. 9:40

Ответы

  • Всем спасибо за советы=)

    Но проблема была как говорится "не в бабине". =) Все было проще, имитацию использования одного объекта я сделал сам, не добавив после клонирования Object_Count++;, - необходимый по логике скрипта.


    • Помечено в качестве ответа wUI 27 июня 2013 г. 4:09
    27 июня 2013 г. 2:03

Все ответы

  • Что-то "SUM_AGZU.CopyTo(Temp_SUM_AGZU, SUM_AGZU.Length);" и Array.Copy, дают тот-же результат. Где-то я явно запутался. ^_^
    26 июня 2013 г. 9:56
  • Добрый день.

    Один из самых забавных интерфейсов, это IClonable.

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


    26 июня 2013 г. 10:21
    Отвечающий
  • Спасибо за уточнение!=)

    А какой же тогда очевидный выход из сложившейся у меня ситуации? Как получить копию объекта а не ссылку для обработки?

    Известные мне методы(copy, copyTo) создают аналогичный результат.


    • Изменено wUI 26 июня 2013 г. 10:28 уточнение
    26 июня 2013 г. 10:26
  • Клонировать объекты. Вызываете конструктор и копируете из объектов по полям.
    • Предложено в качестве ответа YatajgaEditor 26 июня 2013 г. 15:48
    26 июня 2013 г. 10:30
    Отвечающий
  • Хуже если объекты, на которые ссылаются элементы массива, принадлежат "сложным" классам, то есть у которых в свойствах есть ссылки на другие классы, а у тех есть свой ссылки, итд.

    Можно конечно сериализовать и десериализовать, если классы помечены атрибутом [Seriazable].

    • Изменено Higgs.Boson 26 июня 2013 г. 10:59 Корректировка
    26 июня 2013 г. 10:56
  • Спасибо. Попробую применить ваш совет.
    26 июня 2013 г. 11:02
  • Для глубокого копиравания объектов можно воспользоваться классом MemoryStream. Пример можете посмотреть тут. Для небольших можете сделать так, как предложил Алексей.


    Сделаем содержимое сообщества лучше, вместе!


    • Изменено YatajgaEditor 26 июня 2013 г. 15:49 Правка
    26 июня 2013 г. 15:48
    Модератор
  • Всем спасибо за советы=)

    Но проблема была как говорится "не в бабине". =) Все было проще, имитацию использования одного объекта я сделал сам, не добавив после клонирования Object_Count++;, - необходимый по логике скрипта.


    • Помечено в качестве ответа wUI 27 июня 2013 г. 4:09
    27 июня 2013 г. 2:03