ОБНОВЛЕНИЕ: Этот вопрос был источником вдохновения для my article on this subject. Спасибо за отличный вопрос!
«continue» и «break» - не более чем приятный синтаксис для «goto». Видимо, давая им милые имена и ограничивая их использование конкретными контрольными структурами, они больше не притягивают гнев «толпы всех« все, что плохо все время ».
Если вы хотите сделать это с продолжением на внешний, вы можете просто определить метку в верхней части внешнего цикла и затем «перейти» к этой метке. Если вы считаете, что это не мешает пониманию кода, то это может быть наиболее целесообразным решением.
Тем не менее, я хотел бы принять это как возможность рассмотреть вопрос о том, может ли ваш поток управления извлечь выгоду из некоторого рефакторинга. Всякий раз, когда у меня есть условные «break» и «continue» в вложенных циклах, я рассматриваю рефакторинг.
Рассмотрим:
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
}
Если нет петель, нет необходимости перерываться или продолжаться!
Вложенные петли только приводят к отчаянию. –