универсальный контейнер в c # проблема изменения элементов контейнера вне контейнера - PullRequest
0 голосов
/ 18 марта 2011

У меня проблема в программировании на c #, и мне нужна помощь, когда я создаю универсальный контейнер в c # и изменяю один из его элементов вне списка, он тоже изменяется, в то время как я хочу сохранить элементы списка, как это было

Я искал область контейнеров или ссылки, но ничего не нашел Кстати, я сталкивался с этой проблемой много раз прежде, и я решил с помощью конструктора копирования следующим образом

List<Object> list=new List<Object>();
list.Add(new Object(object) );

но в этом случае мое решение не действует

 List<List<Object>> allObjects = new List<List<Object>>(1000);
 List<Object> object = new List<Object>();

 for (int i = 0; i < 1000; i++)
 {
            object = new List<Object>();
            //some code here that fill  object list
            allObjects.Add(object);

 }//after filling all the 1000 elements in allObjects list,all the elements of the   //list are 1000 elements with the same value of the last object has been inserted

мое неправильное решение, которое не имеет смысла в решении проблемы

 List<List<Object>> allObjects = new List<List<Object>>(1000);
 List<Object> object = new List<Object>();

 for (int i = 0; i < 1000; i++)
 {
            object = new List<Object>();
            //some code here that fill object list
            allObjects.Add(new List<Object>(object));

 }

Заранее спасибо

Ответы [ 5 ]

1 голос
/ 18 марта 2011

Объекты в C # являются ссылочными типами. Когда вы создаете новый объект, .net отправляет и выделяет память для этого объекта в куче, сама переменная по сути является указателем на этот объект.

Список, «универсальный контейнер», содержит список ссылок на объекты, а не сами объекты. Когда вы получаете объект из списка, то есть: var x = list [10], вы на самом деле просто получаете ссылку на тот же объект, на который ссылается список. Изменяя объект, изменение также будет отражено в объекте, содержащемся в списке.

Чтобы «изменить объект вне списка», и чтобы это изменение не отображалось на объекте внутри списка, вам нужно будет сделать копию этого объекта; Есть несколько способов сделать это, в зависимости от того, чем на самом деле является ваш объект.

Ради этого примера, если вы решите использовать тип структуры вместо базового «объекта», вы испытаете поведение, которое ищете. Структура в c # не является ссылочным типом.

Надеюсь, я вас больше не смутил?

Прочитав ваш комментарий, попробуйте что-то вроде этого.

List<object> list2 = new List<object>();
for(int i = 0; i < 1000; i++)
{
   List<object>list1 = new List<object>();
   for(int j = 0; j< 1000; j++)
   {
      list1.Add( "something" + j);
   }
   list2.Add(list1);
}

Выше будет создан список, содержащий 1000, списки длиной 1000.

0 голосов
/ 18 марта 2011

Спасибо всем за ваши вдохновляющие ответы и извините за беспокойство, я обнаружил, что проблема в том, что сам внутренний список заполняется повторяющимися данными (использовался генератор случайных чисел, и он повторял данные)это не проблема ссылок, как я думал

0 голосов
/ 18 марта 2011

Я думаю, что ваша проблема внутри " кода, который заполняет список объектов ". Объекты, которые вы помещаете во внутренний List (который вы несколько смущенно называете "object"), относятся к ссылочному типу, и вы, вероятно, помещаете ссылки на одни и те же объекты в каждый из внутренних списков. Поэтому, даже если сами внутренние List являются уникальными экземплярами, то объекты внутри них не являются.

0 голосов
/ 18 марта 2011

В своем комментарии вы говорите:

//after filling all the 1000 elements in allObjects list,all the elements of the
//list are 1000 elements with the same value of the last object has been inserted

, но если вы попробуете что-то простое, например:

List<List<int>> allObjects = new List<List<int>>(10);
for (int i = 0; i < 10; i++)
{
    var obj = new List<int>();
    obj.Add(i);
    allObjects.Add(obj);
}

И проверьте значения списков в отладчике, вы увидите, чтокаждый подсписок имеет один элемент со значением i (от 0 до 9).Поэтому мне кажется, что ваш код работает правильно.

Возможно, проблема возникает после этого кода, когда вы пытаетесь получить доступ к этим элементам в списке, и вы действительно получаете доступ только к последнему элементу.

Или, может быть, ваш класс Object является классом синглтонного типа, который может иметь только один экземпляр (вероятно, не просто что-то, что приходит на ум без знания какой-либо информации об Object).

0 голосов
/ 18 марта 2011

следующее:

object = new List<Object>();
allObjects.Add(object);

эквивалентно:

allObjects.Add(new List<Object>());

, что также эквивалентно:

object = new List<Object>();
allObjects.Add(new List<Object>(object));

В последнем случае вы создаете пустой список, а затем создаете другой пустой список, который вы заполняете первым списком.

Редактировать : Я хотел бы добавить к тому, что сказал Джон, оставив эту ссылку здесь: http://www.yoda.arachsys.com/csharp/parameters.html

Это должно помочь вам понять разницу между значениями и ссылочными типами, так как я думаю, что именно здесь вы запутались.

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