2015-02-25 2 views
2

У меня есть цикл:Deep копия объекта в список

List<A> list = new List<A>(); 
A obj = new A(); 

for (int i = 0; i < 10; ++i) 
{ 
    obj.num = i; // Assigns the current i to the num attribute inside obj 
    list.Add(obj); 
} 

Однако, в этом случае, когда я изменить obj, будут изменены предыдущие экземпляры obj уже добавлены в list. Как написать код, чтобы все, что добавлено в список, больше не ссылалось на текущее значение obj?

+2

Это не имеет ничего общего с глубоким копированием –

+0

Есть ** нет ** * предыдущие экземпляры * вообще в вашем коде. Там просто * один *, который вы переписываете. –

ответ

1

вы должны переместить декларацию obj переменных внутри цикла для

List<A> list = new List<A>(); 

for (int i = 0; i < 10; ++i) 
{ 
    A obj = new A(); 
    obj.num = i; // Assigns the current i to the num attribute inside obj 
    list.Add(obj); 
} 

это все только о переменных областях. здесь obj scope находится внутри итерации цикла. если вы хотите использовать переменную между итерациями, вы должны определить ее из цикла for, как раньше, как вы объявили obj.

+0

Спасибо. Но еще вопрос. Что делать, если мне нужно, чтобы значения 'obj' сохранялись с каждой итерацией цикла? Например, если 'obj.num' зависит от предыдущего значения' obj'? –

+0

@JohnTan Ну, все они в списке, поэтому у вас есть к ним доступ. –

3

Вы можете создать новыйList<A> через Linq вместо добавления:

List<A> list = Enumerable 
    .Range(0, 10) 
    .Select(i => new A() { num = i }) 
    .ToList(); 

Если вы предпочитаете добавлять

List<A> list = new List<A>(); 

for (int i = 0; i < 10; ++i) 
    list.Add(new A() {num = i}); // <- Adding new (copied) instance 
+0

Был готов опубликовать тот же ответ - только отступы были разными! – Enigmativity

0

Это происходит потому, что вероятноA obj = new A(); это в качестве ссылки объект. Поэтому всякий раз, когда вы находитесь в цикле, он также меняет объект, добавленный в список.

Что вы можете сделать, это либо

  1. Создание объекта внутри цикла, а затем добавить его.

    for (int i = 0; i < 10; ++i) 
    { 
        A obj = new A(); // create here so it's a new object always 
        obj.num = i; // Assigns the current i to the num attribute inside obj 
        list.Add(obj); 
    } 
    
  2. Сделайте A Типу IClonable

    class A : ICloneable 
    { 
        public object Clone() 
        { 
         return this.MemberwiseClone(); 
        } 
    } 
    

, а затем просто отлит в перед добавлением. не

List<A> list = new List<A>(); 
A obj = new A(); 
obj.num = 0; 

for (int i = obj.num; i < 10; ++i) 
{ 
    var clonedObj = obj.Clone() as A; // cast to be able to add in the collection 
    clonedObj.num = i; 
    list.Add(clonedObj); 
} 
+1

(2) просто неправильно. –

+0

@ OndrejTucny yah, был на встрече, когда я сделал код, поэтому у меня не было так много времени, чтобы думать. Ну, '(2)' просто решает '' Deep Copy ''он хочет – DevEstacion

Смежные вопросы