Last Updated: May 22, 2026
break and continue are two small keywords that change how a loop runs. break stops the loop entirely. continue skips the rest of the current iteration and jumps to the next one. They're useful whenever you want to exit early on a match, ignore certain items mid-loop, or short-circuit a search the moment you find what you're looking for.
Loops are uniform by design. A for or foreach walks every item, runs the same body each time, and only ends when the loop condition says so. That's what you want most of the time. But not always.
Consider summing prices in a cart until the total crosses a budget. You don't need to add every item, you want to stop the moment you go over. Or listing products on a page and skipping the ones currently out of stock. The loop should keep running, just not for those entries.
That's the gap break and continue fill. They let you change the flow of a single iteration without rewriting the loop or wrapping it in a more complicated structure.
The diagram captures the idea: at any point inside the loop body, break walks out of the loop and continue cuts the current iteration short. Anything else runs to the bottom of the body normally. The rest of this chapter is about the details.
break Statementbreak exits the nearest enclosing loop immediately. Control jumps to the first statement after the loop, skipping any remaining iterations.
The classic use is "stop as soon as you find what you're looking for." A search through a product list:
Once the loop hits "Mouse", it records the index and exits. The remaining products ("Monitor" and "Webcam") are never touched. Without break, the loop would keep checking every item, doing pointless work after the answer was already known.
The same pattern shows up in budget-style problems. Consider a customer with $50 to spend and you want to know how many items from their wishlist fit before they run out of money:
The loop adds 12.99, then 24.50, then 9.75. When it considers 18.00, the running total would jump to 65.24, which is over budget. break ends the loop there, leaving spent at 47.24 and itemsBought at 3. Without break, you'd need a flag variable and an extra condition in the loop header, which is more code for the same behavior.
A break itself is free. The benefit is that the loop stops doing work the moment it has the answer. On long lists or large datasets, that's the difference between O(n) and O(k) where k is the index of the match.
break works in every loop type: for, while, do-while, and foreach. The behavior is identical in each.
while (true) is an infinite loop on its face. break is what gives it an exit. This pattern (loop forever, break inside on a condition) is common when the exit condition isn't a clean expression you can put at the top of the loop.
continue Statementcontinue skips the rest of the current iteration and jumps to the next one. The loop keeps running, you just stop running the rest of the body for this one round.
The most common use is filtering. You want to process most items in a list, but a few should be ignored. Listing products on a page while skipping the ones that are out of stock:
The Keyboard and Monitor lines are skipped because their stock is zero. The continue jumps over the Console.WriteLine and goes straight to the next iteration.
You could rewrite this with a single if:
For one filter, that's arguably cleaner. continue is useful when there are several reasons to skip an item, or when the body of the loop is long. Stacking guard clauses with continue at the top of the body keeps the indentation flat:
Without continue, you'd nest three if blocks and the display logic would sit four levels deep. The flat form reads better.
continue in a for LoopOne detail about continue inside a for loop: the iterator expression (the i++ part) still runs. continue doesn't skip it.
The order of events for a for loop is:
continue is hit, jump straight to step 4.i++ or whatever it is).So a continue jumps to step 4, not step 2. That's important because it means continue in a for loop won't accidentally create an infinite loop. The counter still moves forward.
When i is even, the body is skipped, but i++ still runs. The loop moves through 0, 1, 2, 3, 4 and prints only the odd values.
continue in a while Loopwhile loops don't have a built-in iterator. If your loop counter is updated inside the body and you continue before reaching that update, you'll loop forever. The classic bug:
The fix is to update the counter before continue:
This is one reason foreach and for are usually more convenient than while for collection-style loops: the iterator runs automatically and continue can't leave it behind.
break vs continue Side by SideSame loop, same data, different keyword. The contrast on one example:
With break, the loop stops the first time it sees a zero. With continue, the loop only skips the zeros and keeps going through the rest. Same data, completely different result. Picking the appropriate keyword for the situation is the skill.
Use break when one match is enough to be done. Use continue when one item should be ignored but the rest still matter.
break Only Exits One Levelbreak and continue always target the nearest enclosing loop. If you have a loop inside another loop, a break inside the inner loop exits the inner loop only. The outer loop keeps running.
Consider a search through a 2D grid of product categories and items, looking for a specific product:
The break exits the inner for (the column loop) the moment it finds "Mouse". The outer for (the row loop) doesn't know anything happened. It moves to the next row and keeps searching, even though you've already found what you needed. The code still gives the right answer because foundRow and foundCol aren't overwritten, but the loop does extra work.
You usually want to exit both loops together. C# does not have labeled break or continue. If you need to exit multiple nested loops at once, the options are:
return from inside.bool flag and check it in the outer loop.goto with a label after the outer loop.This is the simplest option in most cases. A method has a natural exit (return), so a single return walks out of however many nested loops you're in.
return (row, col); exits both loops and the method in one step. No flags, no labels, no double-break. The code also reads better because the search has a name and a clear contract: give me a grid and a target, get back a location.
If extracting a method isn't a good fit (maybe the loop touches a lot of local state), a flag does the job. Set it inside the inner loop and check it in the outer loop's header.
The outer loop's condition gains && !found, so once the flag flips, the outer loop ends on its next iteration check. The inner break ends the inner loop right away, and the outer loop exits on the next check. The behavior is correct, just a little noisier than the method version.
goto to a Labelgoto is the third option, and the only one that exits both loops in one statement without restructuring code. The full coverage of goto is in the _goto Statement_ lesson; the example below is a small preview.
goto Done; jumps to the line labeled Done:, which sits after both loops. Both loops exit at once. This is the closest C# gets to a labeled break, and goto for this specific case is fine, even Microsoft's own coding guidelines accept it for nested-loop exits. Save the deeper discussion of goto for the _goto Statement_ lesson.
| Approach | When it fits |
|---|---|
Extract a method, return | Most common. Loops can be named, code reads cleanly. |
| Boolean flag | Outer loop already has shared state you don't want to extract. |
goto with label | A small local block where extraction feels heavy and a flag adds noise. |
continue in Nested Loopscontinue follows the same rule: it skips the rest of the current iteration of the nearest loop. Inside a nested loop, that's the inner loop only.
The continue skips even numbers, but only within the inner loop. The outer loop continues to the next row normally. Every row is visited, just with the even values printed-skipped.
break Inside switch Inside a Loopbreak does double duty in C#. It exits a loop, and it ends a switch case. When you nest a switch inside a loop, break exits the switch, not the loop. The loop keeps running.
This is easy to miss when break is meant to leave the loop entirely.
The break inside the case "cancelled": block ends the switch, then the foreach continues to the next item. If you wanted to actually stop the loop on a cancellation, you need a different exit:
Now the break inside case "cancelled": ends the switch and sets a flag, then the loop's own if (stopped) break; ends the loop. Two breaks, two distinct jobs.
The rule about break in switch cases (it's required, even when the case can't fall through) belongs to the chapter on switch statements. For now, know that a break inside a switch never escapes the loop.
A common cleanup is to replace the switch with an if/else if, since none of the cases need the special switch semantics:
Now break leaves the loop.
break and continue Become a Smellbreak and continue are tools. A loop with one well-placed break or one guard continue reads fine. A loop with five break paths and three continue paths is doing too much.
Heavy nesting plus multiple breaks is usually a sign that the loop body is its own function in disguise. Extracting it gives you a single return instead of scattered exits:
Before (hard to follow):
After (each step has a name):
The continue in the outer loop is a guard against orders that shouldn't be processed. Everything else moves into ProcessOrder, which can return early on its own.
A short checklist when you're tempted to add a third or fourth break:
continues really one combined filter you can compute once?If any answer is yes, extract.
A small end-to-end example combining everything from this chapter. The program walks through a customer's wishlist, skips items that are out of stock or above the per-item price cap, and stops the moment the cart hits the budget.
The output is:
Cable costs 6.99, and the running total before considering it is 69.98. Adding it brings the total to 76.97, which is still under the 100 budget, so it gets added. The break only fires when the next item would push the total over. Tracing through carefully shows two continue paths (out of stock, over cap) and one potential break path (over budget) that didn't trigger this time.
The program reads top-down. Three filters at the top of the loop body, then the real work below. That's the pattern: filter early with continue, exit on completion with break, and keep the meaningful work flat and easy to scan.