ОБНОВЛЕНИЕ: Этот вопрос был вдохновением для моей статьи на эту тему. Спасибо за отличный вопрос!
«continue» и «break» - не более чем приятный синтаксис для «goto». По-видимому, давая им милые имена и ограничивая их использование определенными структурами контроля, они больше не вызывают гнев толпы «все готы все время плохие».
Если то, что вы хотите сделать, это продолжить до внешнего, вы могли бы просто определить метку в верхней части внешнего цикла и затем "перейти" к этой метке. Если вы считаете, что это не мешает пониманию кода, то это может быть наиболее целесообразным решением.
Однако я бы воспользовался этой возможностью, чтобы подумать, выиграет ли ваш поток управления от некоторого рефакторинга. Всякий раз, когда у меня есть условные «разрыв» и «продолжение» во вложенных циклах, я рассматриваю рефакторинг.
Рассмотрим:
successfulCandidate = null;
foreach(var candidate in candidates)
{
foreach(var criterion in criteria)
{
if (!candidate.Meets(criterion)) // Edited.
{ // TODO: no point in continuing checking criteria.
// TODO: Somehow "continue" outer loop to check next candidate
}
}
successfulCandidate = candidate;
break;
}
if (successfulCandidate != null) // do something
Два метода рефакторинга:
Сначала извлеките внутренний цикл в метод:
foreach(var candidate in candidates)
{
if (MeetsCriteria(candidate, criteria))
{
successfulCandidate = candidate;
break;
}
}
Во-вторых, могут ли все петли быть устранены? Если вы зацикливаетесь, потому что пытаетесь что-то найти, то выполните рефакторинг в запрос.
var results = from candidate in candidates
where criteria.All(criterion=>candidate.Meets(criterion))
select candidate;
var successfulCandidate = results.FirstOrDefault();
if (successfulCandidate != null)
{
do something with the candidate
}
Если петель нет, разрывать или продолжать не нужно!