2015-12-03 1 views
7

Примечание: Это уже работает отлично, но я пытаюсь понять, почему он работает таким образом, но не другим.Путаница кода - почему одна работает, но не другая?

У меня есть WinForm (C#) с динамически помещать изображения, например, так: enter image description here

Теперь, если нажать на кнопку «Napred», эти изображения должны быть удалены (среди прочего), для которых я первоначально используется:

foreach(Control ctrl in Controls) 
    if(ctrl is PictureBox) ctrl.Dispose(); 

или

for(int i = 0; i < Controls.Count; i++) 
    if(Controls[i] is PictureBox) Controls[i].Dispose(); 

Теперь, если я запускаю это, я получаю:

enter image description here

Но если я просто изменить for заявление, чтобы отправить его назад, он работает?

for(int i = Controls.Count - 1; i >= 0; i--) 
    if(Controls[i] is PictureBox) Controls[i].Dispose(); 

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

Может кто-нибудь просветить меня, почему один работает , но не другой?

EDIT: Я использую VS2015 Community Edition на Windows 10, если это ошибка отладки

+0

Если у вас есть массив из 10 элементов, а затем удалить ITEM1, Элемент2 станет новым Элемент1 и у вас останется 9 предметов. Стандартный метод утилизации элементов массива состоит в том, чтобы пройти его назад. – LightBulb

+0

Может представлять интерес для других подходов: http://stackoverflow.com/questions/7340757/c-sharp-list-removing-items-while-looping-iterating –

+0

Почему вы не используете метод Remove? –

ответ

12

Вы пытаетесь изменить список вы итерация, что, конечно, будет меняться (?) индексы этого списка, так что индекс индекса 1 теперь находится в индексе 0.

Удалив из конца массива (т.е. в обратном порядке), предыдущие индексы всегда будут одинаковыми.

Ее также важно отметить, как говорится в комментарии Мэтью Уотсона:

Control.Dispose() является специальным и удалит элемент управления из списка элементов управления родительского контейнера.

Это не по умолчанию behavour большинством Dispose методов так поэтому вы не всегда находят такое поведение при использовании Dispose

+1

Я понимаю, поэтому каждый второй элемент удаляется. Спасибо, что поняли! Это совсем не переходило мне на ум! – NemanjaT

+2

Я думаю, вам должно быть ясно, как он меняет список, над которым он выполняет итерацию, потому что, просто проверяя код, он не удаляет элементы из списка напрямую. Ответ заключается в том, что 'Control.Dispose()' является специальным и удалит элемент управления из списка 'Controls' родительского контейнера. –

+0

@MatthewWatson - Очень верно, я пытался сохранить этот родословный в ссылках на сами списки. – Sayse