Цикл C# - break vs. continue

В цикле C# (не стесняйтесь отвечать для других языков), какая разница между break и continue как средством выхода из структуры цикла и перехода к следующей итерации?

Пример:

foreach (DataRow row in myTable.Rows)
{
    if (someConditionEvalsToTrue)
    {
        break; //what's the difference between this and continue ?
        //continue;
    }
}

сообщение в блоге с кульминацией ниже adamthings.com/post/2012/07/26/…

Adam 20.06.2013 02:05

continue; остановит обработку текущего row и продолжит обработку следующийrow из коллекции. С другой стороны, break; полностью покинет оператор foreach, а оставшиеся строки никогда не будут обработаны.

Jeppe Stig Nielsen 29.12.2017 17:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
816
3
766 278
15
Перейти к ответу Данный вопрос помечен как решенный

Ответы 15

break полностью остановит цикл foreach, continue перейдет к следующему DataRow.

Ответ принят как подходящий

break полностью выйдет из цикла, continue просто пропускать текущей итерации.

Например:

for (int i = 0; i < 10; i++) {
    if (i == 0) {
        break;
    }

    DoSomeThingWith(i);
}

Разрыв вызовет выход из цикла на первой итерации - DoSomeThingWith никогда не будет выполнен. Это здесь:

for (int i = 0; i < 10; i++) {
    if (i == 0) {
        continue;
    }

    DoSomeThingWith(i);
}

Не будет выполнять DoSomeThingWith для i = 0, но цикл будет Продолжить, а DoSomeThingWith будет выполняться для i = 1 - i = 9.

Почему у них нет подтяжек - я знаю, что без них это работает, но почему?

George Willcox 08.07.2016 19:06

@GeorgeWillcox Моя юная и глупая личность еще не всегда понимала ценность скобок. (Они являются необязательными в C# для отдельных операторов, но их отсутствие упрощает внесение ошибки позже. Также см. programmers.stackexchange.com/a/16530/6342)

Michael Stum 08.07.2016 20:20

Самый простой способ понять это - поместить слово «цикл» после каждого ключевого слова. Теперь термины имеют смысл, если их просто читать как обычные фразы.

break loop - зацикливание прерывается и останавливается.

continue loop - цикл продолжает выполняться со следующей итерации.

Многим людям не нравятся break и continue. Последняя жалоба, которую я видел на них, была в JavaScript: хорошие стороны Дугласа Крокфорда. Но я считаю, что иногда использование одного из них действительно упрощает ситуацию, особенно если ваш язык не включает стиль цикла do-while или do-until.

Я обычно использую break в циклах, которые ищут что-то в списке. После того, как вы нашли, нет смысла продолжать, так что вы можете уйти.

Я использую continue, когда что-то делаю с большинством элементов списка, но все же хочу пропустить некоторые.

Заявление break также может пригодиться при запросе правильного ответа от кого-то или чего-то. Вместо:

Ask a question
While the answer is invalid:
    Ask the question

Вы можете устранить некоторое дублирование и использовать:

While True:
    Ask a question
    If the answer is valid:
        break

Цикл do-until, о котором я упоминал ранее, является более элегантным решением этой конкретной проблемы:

Do:
    Ask a question
    Until the answer is valid

Никакого дублирования, и никакого break тоже не требуется.

К сожалению, Ruby немного отличается. PS: Моя память немного туманна по этому поводу, поэтому извиняюсь, если я ошибаюсь

вместо break / continue у него есть break / next, которые ведут себя одинаково с точки зрения циклов.

Циклы (как и все остальное) являются выражениями и «возвращают» последнее, что они сделали. В большинстве случаев получение возвращаемого значения из цикла бессмысленно, поэтому все просто делают это.

a = 5
while a < 10
    a + 1
end

Однако вы можете сделать это

a = 5
b = while a < 10
    a + 1
end # b is now 10

ОДНАКО большая часть кода Ruby «эмулирует» цикл с помощью блока. Канонический пример:

10.times do |x|
    puts x
end

Поскольку люди гораздо чаще хотят что-то делать с результатом блока, именно здесь это становится беспорядочным. break / next означают разные вещи в контексте блока.

break выскочит из кода, который вызвал блок

next пропустит остальную часть кода в блоке и «вернет» то, что вы укажете, вызывающей стороне блока. Без примеров это не имеет смысла.

def timesten
    10.times{ |t| puts yield t }
end


timesten do |x|
   x * 2
end
# will print
2
4
6
8 ... and so on


timesten do |x|
    break
    x * 2
end
# won't print anything. The break jumps out of the timesten function entirely, and the call to `puts` inside it gets skipped

timesten do |x|
    break 5
    x * 2
end
# This is the same as above. it's "returning" 5, but nobody is catching it. If you did a = timesten... then a would get assigned to 5

timesten do |x|
    next 5
    x * 2
end 
# this would print
5
5
5 ... and so on, because 'next 5' skips the 'x * 2' and 'returns' 5.

Так что да. Ruby прекрасен, но у него есть несколько ужасных угловых моментов. Это второй худший вариант, который я видел за годы его использования :-)

перемена заставляет счетчик программы выскакивать из области самого внутреннего цикла

for(i = 0; i < 10; i++)
{
    if (i == 2)
        break;
}

Работает так

for(i = 0; i < 10; i++)
{
    if (i == 2)
        goto BREAK;
}
BREAK:;

Продолжить переходит в конец цикла. В цикле for continue переходит к выражению приращения.

for(i = 0; i < 10; i++)
{
    if (i == 2)
        continue;

    printf("%d", i);
}

Работает так

for(i = 0; i < 10; i++)
{
    if (i == 2)
        goto CONTINUE;

    printf("%d", i);

    CONTINUE:;
}

Я заметил, что многие циклы здесь просто используют стандартный цикл for, но будет ли это работать для циклов while до и после тестирования? Обозначение goto наводит меня на мысль, но требует некоторой проверки.

Daniel Park 08.08.2013 07:02

@Daniel, для циклов WHILE вы можете использовать BREAK и CONTINUE, без проблем.

Amila 21.04.2015 08:09

@DanielPark Как для while («предварительно протестировано»), так и для do-while («после проверки»), после того, как оператор continue; будет выполнен, следующее, что произойдет, это то, что условие цикла будет оценено, чтобы решить, требуется ли дополнительная итерация. должно быть сделано. Конечно, с break; проверяется условие цикла нет, цикл просто полностью завершается. Так что аналогия с goto хороша и для понимания этого аспекта.

Jeppe Stig Nielsen 29.12.2017 17:16

Простой ответ:

Перемена немедленно выходит из цикла. Продолжать начинает обработку следующего элемента. (Если есть, перейдя к строке оценки for / while)

Позвольте мне заявить очевидное: обратите внимание, что добавление ни break, ни continue, не возобновит вашу программу; то есть я поймал определенную ошибку, затем, зарегистрировав ее, я хотел возобновить обработку, и между следующей строкой было больше задач кода, поэтому я просто позволил ей провалиться.

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

// break statement
for (int i = 0; i < 5; i++) {
    if (i == 3) {
        break; // It will force to come out from the loop
    }

    lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}

Вот результат:

0[Printed] 1[Printed] 2[Printed]

Таким образом, 3 [Напечатано] и 4 [Напечатано] не будут отображаться, поскольку есть разрыв, когда i == 3

//continue statement
for (int i = 0; i < 5; i++) {
    if (i == 3) {
        continue; // It will take the control to start point of loop
    }

    lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}

Вот результат:

0[Printed] 1[Printed] 2[Printed] 4[Printed]

Таким образом, 3 [Printed] не будет отображаться, поскольку есть continue, когда i == 3

Чтобы полностью выйти из цикла foreach, используется перемена;

Для перехода к следующей итерации цикла используется Продолжить;

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

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

Перемена

Break заставляет цикл немедленно выйти.

Продолжать

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

Продолжить тоже проверяет условие цикла :)

Grantly 02.12.2017 01:04

Continue не является противоположностью break, break останавливает цикл, continue останавливает текущую итерацию.

Steven 29.03.2018 15:39

На примере

foreach(var i in Enumerable.Range(1,3))
{
    Console.WriteLine(i);
}

Печатает 1, 2, 3 (на отдельных строках).

Добавить условие разрыва при i = 2

foreach(var i in Enumerable.Range(1,3))
{
    if (i == 2)
        break;

    Console.WriteLine(i);
}

Теперь цикл печатает 1 и останавливается.

Замените разрыв продолжением.

foreach(var i in Enumerable.Range(1,3))
{
    if (i == 2)
        continue;

    Console.WriteLine(i);
}

Теперь зацикливаем отпечатки 1 и 3 (пропуская 2).

Таким образом, break останавливает цикл, тогда как continue переходит к следующей итерации.

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

for(int i = 0; i < list.Count; i++){
   if (i == 5)
    i = list.Count;  //it will make "i<list.Count" false and loop will exit
}

Хотя это работает, это не лучший подход. Ключевое слово break обозначает ваше намерение. Если бы я это увидел, мне было бы интересно, что происходит ... Мне потребовалось бы несколько дополнительных тиков, чтобы понять, почему кто-то это делает. break существует для этой цели, и глупо делать что-то более запутанное, просто чтобы избежать использования ключевого слова.

Mike Christiansen 16.01.2021 17:32

Раньше я всегда не понимал, следует ли мне использовать паузу или продолжить. Вот что мне помогает запомнить:

Когда использовать break vs continue?

  1. Перемена - это как расставание. Печально, вы, ребята, расстаетесь. Цикл завершен.

Break

  1. Продолжать - означает, что вы сегодня дадите отдохнуть, а завтра разберетесь (т.е. пропустите текущую итерацию)!

Continue

Поделюсь этим со своим партнером. Возможно, Continue следует переименовать в GetOverIt, а Break - в MoveOnForward. Неудивительно, что нас называют гиками, какой смысл в Break? Звучит деструктивно. И еще один, который необходимо добавить, - STOP, или даже лучше EndIt - исправит множество ошибок и сделает C-диез по-настоящему резким.

Mike 05.03.2020 14:29

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

Talal Zahid 03.04.2020 02:48

@TalalZahid я не понимаю?

BKSpurgeon 03.04.2020 04:53

Что касается других языков:

'VB
For i=0 To 10
   If i=5 then Exit For '= break in C#;
   'Do Something for i<5
next

For i=0 To 10
   If i=5 then Continue For '= continue in C#
   'Do Something for i<>5...
Next

Другие вопросы по теме