Как разорвать сразу несколько циклов в C #?

Что делать, если у меня есть вложенные циклы, и я хочу разорвать их все сразу?

while (true) {
    // ...
    while (shouldCont) {
        // ...
        while (shouldGo) {
            // ...
            if (timeToStop) {
                break; // Break out of everything?
            }
        }
    }
}

В PHP break принимает аргумент для количества выходных циклов. Можно ли что-то подобное сделать на C #?

А что насчет чего-нибудь ужасного, например goto?

// In the innermost loop
goto BREAK
// ...
BREAK: break; break; break;

person Nick Heiner    schedule 26.02.2010    source источник
comment
это неправильный синтаксис для goto. просто положите этикетку за петли и нигде не делайте разрывов.   -  person Jimmy    schedule 26.02.2010
comment
Дубликат: stackoverflow.com/questions/1586932/   -  person Foole    schedule 26.02.2010
comment
Обратите внимание: blogs.msdn. com / ericlippert / archive / 01.01.2010 /   -  person Eric Lippert    schedule 26.02.2010
comment
Эрик: Ваш блог - важная информация для разработчиков C #. Большое спасибо за всю информацию, которую вы там публикуете !!!   -  person Bob Denny    schedule 26.02.2010
comment
возможный дубликат выхода из вложенного цикла   -  person Stewart    schedule 17.09.2015


Ответы (4)


Извлеките вложенные циклы в функцию, а затем вы можете использовать return для выхода из цикла из любого места, а не break.

person Michael Anderson    schedule 26.02.2010
comment
это хак, а не то, для чего нужны функции, большинство людей, которые ненавидят goto, считают ранний возврат в функциях столь же плохим. Я не согласен с такими широкими утверждениями, но я бы сказал, что использование goto так же верно, как и это решение проблемы, хотя, конечно, не так аккуратно. - person matt; 09.03.2010
comment
Я полностью не согласен, Мэтт. Число людей, которые верят в необходимость единственного выхода из функций, намного меньше, чем тех, кто ненавидит gotos. Причина в том, что на многих языках goto не выполняет правильную очистку ресурсов (точно не знаю о C #), а return выполняет. Также функции IMHO предназначены для группировки, определения объема и упрощения связанного кода. Это именно то, что он делает. - person Michael Anderson; 09.03.2010
comment
Я согласен с этим ответом. Одна из причин помещения вложенных циклов в отдельную функцию заключается в том, что исходная функция становится слишком большой. Если исходная функция настолько велика, вложенные циклы - хорошее место, чтобы разбить функцию на две функции. У вас есть задача A, которая представляет собой серию вложенных циклов, затем вы хотите перейти к задаче B после того, как циклы найдут то, что они ищут. Если вы считаете, что получение нескольких возвратов является проблемой, это признак того, что ваша функция слишком велика. - person Russell Hankins; 05.12.2016
comment
У нас в 2018 C # есть все навороты ... Но до сих пор нет многоуровневого перерыва или продолжения ... - person Calmarius; 14.08.2018

Введите еще один контрольный флаг и поместите его во все ваши вложенные условия, как показано ниже. Также заменяет имеющееся у вас условие while (true) на это

bool keepLooping = true;
while (keepLooping) {
    // ...
    while (shouldCont && keepLooping) {
        // ...
        while (shouldGo && keepLooping) {
            // ...
            if (timeToStop) { 
                keepLooping  = false;
                break; // break out of everything?
            }
        }  
    }
}
person Fadrian Sudaman    schedule 26.02.2010
comment
+1 Очень красиво! :) Я опубликовал что-то похожее на это, но ваше было лучше, поэтому я удалил его. - person Mark Carpenter; 26.02.2010
comment
Хотел бы я проголосовать за это более одного раза. 'If (timeToStop && keepLooping)', вероятно, может потерять часть 'keepLooping', кроме этого, великолепно! - person Mark Carpenter; 26.02.2010
comment
Я не понимаю, как это легче читать, чем goto? вам нужно придумать имя переменной, которое описывает ее намерение вырваться из всех циклов, почему бы вам просто не приложить те же усилия, чтобы придумать имя для метки goto? это ведь медленнее. вы должны искать везде, где используется keepLooking, а не только одну метку. - person matt; 09.03.2010
comment
Отредактировано, чтобы удалить ненужный keepLooping в последнем цикле, как это было предложено @Pwninstein - person Fadrian Sudaman; 09.03.2010
comment
@Matt - Конечно, вы можете сделать то же самое, но в личных предпочтениях я воспользуюсь вышеуказанным, а не GOTO. В этом сценарии GOTO может быть таким же читаемым, но во многих случаях GOTO может сделать код очень нечитаемым и действительно нежелательным в среде структурного программирования. Большинство руководств по кодированию, которые я видел, отошли от него, и зачем ломать его из-за простой структурной проблемы, как указано выше? Единственный раз, когда я использовал GOTO и нашел его действительно полезным, - это когда я написал сложный синтаксический анализатор, в котором мне нужно интерпретировать токен по сотням ключевых слов с некоторой интересной повторяющейся логикой. - person Fadrian Sudaman; 09.03.2010
comment
lol, ничто так не проверяет пределы структурного программирования, как синтаксический анализ. - person matt; 09.03.2010
comment
Если ваши циклы предназначены для операторов, все, что вам нужно сделать, это взять значение итерации и установить его на максимальное значение или выше, вы можете сделать это для текущего for, но также и для каждого внешнего for ... Мне пришлось сделать это, когда я имел четыре вложенных оператора FOR и требовалось вырваться из двух самых внутренних. - person TravisO; 07.03.2019

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

Краткий ответ: Нет.

person Andrew    schedule 26.02.2010
comment
+1. По сути, каждая управляющая структура находится goto внизу; просто вписывались в конкретную цель. Для всего, что не охвачено этими специальными целями, нет другого «элегантного» варианта, кроме goto. - person Joey; 26.02.2010
comment
IMO GOTO ужасен только тогда, когда используется вне программирования на ассемблере. К каждому его собственное, хотя :) - person Mark Carpenter; 26.02.2010
comment
С точки зрения структурированного программирования goto - это просто конструкция низкого уровня, на которой реализуются конструкции выбора и итерации высокого уровня. Вернуть, прервать и продолжить разорвать модуль структурированного программирования и фактически являются просто частными случаями goto, но, тем не менее, я думаю, что их полезность имеет тенденцию выигрывать. - person Stewart; 17.09.2015

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

if (TimeToStop)
{
   return;
}
person tolu619    schedule 08.02.2012