Several big reasons for not implementing continue (or refactoring to remove it whenever possible)
- Your loop is inefficient - If you are using
continue
, then the loop you are using is processing elements in the list it does not need to look at. Now with Jitted compilers or VM systems like Java, C# the compiler will often simplify the and refactor the list when it compiles. But you may still rack up the memory as additional objects may be stored. Lower level languages will show a huge hit. Refactor your loop statement to only loop through only elements that need to be affected.
- You are changing where the responsibility/logic of the loop lies - A loop is defined by it's declaration, this is where all control of the loop should be. By using
continue
(and to a lesser extent 'break') you are making 2 different lines responsible for the loop logic, worse: the continue could be anywhere inside the code inside the loop (see next point).
- You are making it harder for any code changes to occur and may introduce bugs - This may not seem obvious with tutorials and other simple examples but even with only 10 -20 lines of code in the loop this WILL cause problems on production code. Lets say you have a loop through objects and you look at a param on the object to determine if you want to continue at a certain point. Now when that object is changed in the future and that param may be altered, you not only have to look at any loop logic to make sure it is updated, but you already need to know a continue is used in the loop, and find it and alter it as well. With even only 10-20 lines of code inside a loop, this can be missed easily, leading to a situation where the person updating the code knows they checked the loop logic and goes hunting for the inevitable bug elsewhere.
Some Examples:
Continue used unnecessarily looping through unneeded items:
foreach(var item in list) {
if(item.param3 == "hippies") continue;
//edit the item here
}
Refactored (uses less memory & cpu):
foreach(var item in list.Where(x => x.param3 != "hippies")) {
//edit item here
}
continue used to only update some parts of a list item.
for(var item in itemList) { //must always be checked with any object change
item.param1 = 45;
item.param2 = "this is a thing";
if(item.param3 == "hippies") continue; //must be checked with any object code change
item.param3 = "dodgy code"
DoThisCode(item);
}
Now imagine the above example if item.param3 is altered in the object code to never be (or is always) equal to "hippies", imagine this with with 20 - 50 lines of code in the loop (bad practice but it happens) with a continue dumped into the middle, or even worse imagine a newParam
is added, and the loop should now do something only when newParam meets a certain condition and param3 is not equal to hippies. The person doing the update has to know that continue is in use and update it correctly as well as check the loop conditional and make sure it is good even though it may state the opposite of what they are looking for (param3 == "hippies" instead of != "hippies" or another set of values)
Last example (based on a real project developed in 2018 I had to update, this is massively simplified, the real loop code was 42 lines long)
foreach(var item in list) {
if(item.param1 == condition)
{
someChangesMadeToItem(item);
}
else if(item.param3 == condition)
{
someMoreChangesMadeToItem(item);
}
//another 5-6 lines of code.
if(item.param2 == condition) {
continue;
}
someMoreChangesMadeToItem(item);
//another 20+ lines of code here
result.add(item);
}
return result;
In the above example another param was added to the object that was supposed to disallow adding to the results (replacing the prior logic).
So not only was the loop processing unnecessary items, it was executing multiple lines of code on those items when they were never output (as they were never added to the result), and when updated I updated the loop logic with a .Where(x => x.NewParam condition)
and missed the continue in the middle of the code, this led to most of the output being correct, but some items being missed for no immediately apparent reason (where the old conditional for the continue held true) and only by stepping through the code and checking the list did I see the conditional as there were multiple function calls within the loop and the issue could have been occurring in any of them.
continue
. – Debunk