2012-02-10 2 views
3

Я всегда был смущен этим. Рассмотрим следующие циклы:NET loop целостность 101

int [] list = new int [] { 1, 2, 3 }; 
for (int i=0; i < list.Length; i++) { } 
foreach (int i in list) { } 
while (list.GetEnumerator().MoveNext()) { } // Yes, yes you wouldn't call GetEnumerator with the while. Actually never tried that. 
  • [Список] выше жестко закодирован. Если список был изменен внешне, когда цикл проходил через итерации, что произойдет?
  • Что делать, если [list] является свойством readonly, например. int List{get{return(new int [] {1,2,3});}}? Будет ли это нарушать цикл. Если нет, создаст ли он новый экземпляр на каждой итерации?

ответ

6

Ну:

  • В for проверяет цикл против list.Length на каждой итерации; вы фактически не получаете доступ к list внутри цикла, поэтому содержимое будет неупорядоченным
  • В цикле foreach используется только list для получения итератора; изменить его, чтобы ссылаться на другой список, не имеет никакого значения, но если вы изменили его сам по себе структурно (например, добавив значение, если это действительно было List<int> вместо int[]), это приведет к аннулированию итератора
  • Ваш третий пример, как написано, будет продолжаться вечно, если список не будет очищен, учитывая, что он будет каждый раз получать новый итератор. Если вы хотите более разумное объяснение, опубликовать более разумного код

Фундаментально вы должны понимать разницу между содержимым массива против изменения, какой объект переменного относится к - и затем дать нам очень конкретную ситуации объяснить. В общем случае цикл foreach непосредственно затрагивает исходное выражение один раз, когда он извлекает итератор, тогда как цикл for не имеет в себе никакой магии, и как часто он доступен, просто зависит от кода - как условие, так и «шаг», часть цикла for выполняется на каждой итерации, поэтому, если вы ссылаетесь на переменную в любой из этих частей, вы увидите любые изменения ...

+1

Другое дело, что для массива свойство 'Length' равно неизменный. Если вы вызываете 'Length' в массиве и получаете определенное значение, все будущие вызовы' Length' для этого массива гарантированно возвращают одинаковое значение. Конечно, если у вас есть переменная экземпляра типа массива, и что-то изменяет эту переменную экземпляра на другой массив, длина этого массива может отличаться от предыдущей. – supercat