UPDATE: This question was inspired by my article on this subject. Thanks for the great question!
"continue" and "break" are nothing more than nice syntax for "goto". Apparently, giving them cute names and restricting their use to specific control structures, they no longer gain the ire of "the crowds of all yearlings - everything is bad."
If what you want to do is a continuation-external, you can simply define a label at the top of the outer loop and then “jump” to that label. If you think that this does not interfere with the understanding of the code, this may be the most appropriate solution.
However, I would like to consider this as an opportunity to consider whether your control flow will benefit from some refactoring. Whenever I have conditional "break" and "continue" in nested loops, I consider refactoring.
Consider:
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
Two refactoring techniques:
First, extract the inner loop into the method:
foreach(var candidate in candidates) { if (MeetsCriteria(candidate, criteria)) { successfulCandidate = candidate; break; } }
Secondly, is it possible to exclude all loops? If you are looping because you are trying to find something, then reorganize it into a query.
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 }
If there are no cycles, then there is no need to interrupt or continue!
Eric Lippert Jul 15 '09 at 19:40 2009-07-15 19:40
source share