2016-07-06 7 views
1

У меня есть объект, который хранит две строки и переопределяет метод ToString(), чтобы вернуть одну из этих строкДобавление пользовательских объектов в проверяемых списки в C#

  fooBar temp; 
      foreach (string foo in bar) 
      { 
       temp = new fooBar(); <--- Why is this line needed when I 
       am overwriting the code and path on each cycle before adding? 

       temp.code += "."; 
       temp.path += "."; 

       Console.WriteLine(temp); 
       clbFooBar.Items.Add(temp); 
      } 

начинает печать на консоль подчиняется перезаписан код и значения строки пути, но элементы отмеченного элемента списка - это все то же самое (ToString() последнего элемента), что происходит в основном процессе, что не сразу становится очевидным?

Если изменить его clbFooBar.Items.Add(temp.ToString()); она работает абсолютно нормально, но это не было бы так же, как temp.ToString.ToString(), потому что .Add звонки .ToString() в первую очередь? Я понял, как консольную печать и .Add будет действовать так же, видя, как они оба называют ToString()

EDIT: temp = new fooBar(); это исправить мою проблему, я просто хочу знать, почему это исправить, когда интуиция заставляет меня думать, что перезапись двух строк, кода и пути, должно быть достаточно, и поэтому без этой повторной инициализации все элементы в отмеченном списке будут одинаковыми.

+0

Вы имеете в виду, что они такие же, если вы _remove_ строка 'temp = new fooBar();'? –

+0

Нет, поле для печати и проверки консоли отображается только в том случае, если эта строка присутствует, что не имеет для меня никакого смысла. – Bradley

+0

Я имел в виду, что элементы в вашем проверочном поле выглядят одинаково, если эта строка _not_ присутствует, но (правильно) другая, если эта строка _is_ присутствует? –

ответ

3

Так ты вопрос, кажется, почему ваш код работает правильно, если вы держать линию

temp = new fooBar(); 

в цикле, но наполнит вашу CheckedListBox со всеми равными предметами, если вы ommit этой строки ,

Причина заключается в том, что если вы создаете только один экземпляр fooBar вне цикла, как, что:

fooBar temp; = new fooBar(); 
foreach (string foo in bar) 
{ 
    temp.code += "."; 
    temp.path += "."; 
    clbFooBar.Items.Add(temp); 
} 

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

При создании новых экземпляров внутри вашей петли так:

foreach (string foo in bar) 
{ 
    fooBar temp; = new fooBar(); 
    temp.code += "."; 
    temp.path += "."; 
    clbFooBar.Items.Add(temp); 
} 

у вас есть новый экземпляр для каждой итерации и не изменять уже добавленные экземпляры.


Update: только что заметил, что они все еще будут выглядеть так же, как вы установите их все к тому, что значение по умолчанию code и temp есть плюс ".".Так что все еще немного неясно, что вы на самом деле пытаетесь сделать. может быть примерно так:

string s = string.Empty; 
foreach (string foo in bar) 
{ 
    s += "."; 
    fooBar temp; = new fooBar(); 
    temp.code = s; 
    temp.path = s; 
    clbFooBar.Items.Add(temp); 
} 
+0

Ах! Итак, что вы говорите, экземпляры, находящиеся в настоящее время в списке отмеченных экземпляров, отражают экземпляр независимо, поэтому они все являются последним элементом, так как именно этот экземпляр теперь добавляет все элементы. Я сделал предположение, что отмеченные элементы списка не являются ссылкой на экземпляр, который вы передаете, но копируете то, что вы передаете. Благодаря! – Bradley

+1

@Bradley: Я говорю, что если вы создаете только один экземпляр, то есть только один экземпляр. Да, вы ввели этот один и тот же экземпляр несколько раз в свой список и изменили его свойства на каждой итерации. Таким образом, последнее изменение - это то, что было показано в вашем проверочном списке. –

+0

Большое спасибо, этот заблудился! Уже пятница? – Bradley

0

Вы создаете temp вне цикла foreach, а затем инициализируете его внутри.

Если вы не повторно инициализируетесь с каждым проходом цикла, то в итоге вы получаете CheckedListBox, где все предметы внутри него указывают на один и тот же объект.

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

Я предполагаю, что то, что вы на самом деле хотите сделать, это добавить каждый элемент (foo) в строке до CheckedListBox. Если это так, используйте это.

 foreach (string foo in bar) 
     { 
      foo.code += "."; 
      foo.path += "."; 

      Console.WriteLine(foo); 
      clbFooBar.Items.Add(foo); 
     } 
+0

Я не думаю, что очень хорошо объясняю, происходит полная противоположность. Если я не повторно инициализирую на каждом проходе, результат состоит в том, что все проверочное поле списка содержит то, что кажется дублирующим последнего элемента. – Bradley

+0

Да, я понимаю. Проблема, как я описал. Вы пробовали мой подход? –

+0

Ваш подход был именно моим подходом, и именно это дало мне проблему в первую очередь. Повторная инициализация устраняет проблему, я просто хочу знать, почему! Haha – Bradley