C# Break Continue
break and continue are C# jump statements that change the normal flow of a loop. break ends the nearest loop immediately, while continue skips the rest of the current iteration and moves to the next one. They matter because real loops often need early exits, filtering, validation, or special-case handling without wrapping the whole loop body in deeply nested if statements.
Overview: How Break and Continue Work
A loop normally follows a predictable path. A for loop runs its initializer once, checks its condition, runs the body, runs its iterator, and repeats. A while loop checks its condition before each body execution. A foreach loop asks an enumerator for the next item until no items remain. break and continue interrupt that ordinary body execution, but they do so in different ways.
break exits the nearest enclosing loop or switch. If the program is inside a loop body and reaches break;, control jumps to the first statement after that loop. The loop condition is not checked again, the remaining statements in the body are skipped, and no later iterations happen. This is useful when the program has found what it was looking for, reached a limit, detected a terminating value, or cannot safely continue.
continue does not end the loop. It skips the remaining statements in the current iteration only. In a for loop, control jumps to the iterator expression, then the condition is checked again. In a while or do loop, control jumps back to the condition check. In a foreach loop, the enumerator advances to the next item. This makes continue a good fit for skipping invalid records, ignored values, or cases that need no further work.
Both statements affect only the nearest loop they are directly inside. In nested loops, a break inside the inner loop exits the inner loop, not the outer loop. If you need to stop multiple levels, you usually use a flag variable, move the search into a method and use return, or restructure the code so one loop owns the stopping condition.
Under the hood, the C# compiler translates these jumps into branch instructions in Intermediate Language. There is no special object allocation and no exception is thrown. The CLR simply follows the branch to the target instruction chosen by the compiler. Because the target is known at compile time, break and continue are fast control-flow tools, but too many jumps in one loop can still make human understanding harder.
Syntax
for (int i = 0; i < count; i++)
{
if (shouldStop)
{
break;
}
if (shouldSkip)
{
continue;
}
// Work for items that were not skipped.
}
| Statement | Effect | Common use |
|---|---|---|
break; |
Immediately exits the nearest loop or switch. |
Stop after finding a match, reaching a sentinel value, or hitting a limit. |
continue; |
Skips the rest of the current loop body and starts the next iteration. | Ignore invalid, empty, disabled, or already-handled items. |
- Both statements must appear inside a valid control-flow context. A
breakcannot appear by itself in the middle of a method unless it is inside a loop orswitch. - Use braces around the related
ifbody so the jump belongs to the condition you intended. - In
whileloops, update counters or input values before a possiblecontinue, or the loop may repeat forever.
Examples
Stopping a Search with Break
using System;
class Program
{
static void Main()
{
int[] stockCounts = { 12, 8, 0, 5, 20 };
int firstEmptyIndex = -1;
for (int i = 0; i < stockCounts.Length; i++)
{
if (stockCounts[i] == 0)
{
firstEmptyIndex = i;
break;
}
}
Console.WriteLine($"First empty shelf index: {firstEmptyIndex}");
}
}
Output:
First empty shelf index: 2
The loop checks each shelf count. Once it finds the first zero at index 2, there is no reason to inspect the remaining shelves. break exits the loop immediately, and execution continues with the final Console.WriteLine.
Skipping Bad Values with Continue
using System;
class Program
{
static void Main()
{
int[] scores = { 90, -1, 75, 101, 84 };
int validCount = 0;
int total = 0;
foreach (int score in scores)
{
if (score < 0 || score > 100)
{
continue;
}
validCount++;
total += score;
}
double average = total / (double)validCount;
Console.WriteLine($"Valid scores: {validCount}");
Console.WriteLine($"Average: {average:F1}");
}
}
Output:
Valid scores: 3
Average: 83.0
The invalid scores -1 and 101 are skipped. Because continue jumps to the next foreach item, the counting and totaling statements run only for valid scores.
Break in a Nested Loop
using System;
class Program
{
static void Main()
{
string[,] seats =
{
{ "taken", "taken", "open" },
{ "taken", "open", "open" }
};
for (int row = 0; row < 2; row++)
{
for (int column = 0; column < 3; column++)
{
if (seats[row, column] == "open")
{
Console.WriteLine($"First open seat in row {row}: column {column}");
break;
}
}
}
}
}
Output:
First open seat in row 0: column 2
First open seat in row 1: column 1
The inner loop searches one row. When it finds an open seat, break exits only that inner column loop. The outer row loop still continues, so the program reports the first open seat in each row.
Continue in a While Loop
using System;
class Program
{
static void Main()
{
int number = 0;
while (number < 6)
{
number++;
if (number % 2 != 0)
{
continue;
}
Console.WriteLine(number);
}
}
}
Output:
2
4
6
This loop prints only even numbers. The counter is incremented before the continue check, which is important. If the increment came after the continue, odd values would keep repeating and the loop might never finish.
How It Works Step by Step
- The compiler parses
break;orcontinue;and verifies that the statement is inside a loop, or forbreak, inside a loop orswitch. - For
break, the compiler chooses the instruction just after the nearest enclosing loop as the jump target. - For
continue, the compiler chooses the next-iteration target: the iterator step forfor, the condition check forwhile, or the enumerator advance forforeach. - At runtime, when execution reaches the jump statement, the CLR branches to that target instead of running the remaining statements in sequence.
- If the loop is inside a
tryblock with afinally, thefinallycode still runs as required by C# control-flow rules.
For foreach, early exit also disposes the enumerator when needed. That matters for enumerators backed by resources such as files, database readers, or custom iterators. You usually do not write that cleanup yourself; the compiler emits the appropriate try and finally structure around the enumeration.
Common Mistakes
Using Break When You Meant Continue
using System;
class Program
{
static void Main()
{
int[] values = { 3, -1, 4, 5 };
int total = 0;
foreach (int value in values)
{
if (value < 0)
{
break;
}
total += value;
}
Console.WriteLine(total);
}
}
Output:
3
This compiles, but it stops at the first negative value and misses later valid values. If negative numbers should be ignored rather than treated as a stopping signal, use continue.
using System;
class Program
{
static void Main()
{
int[] values = { 3, -1, 4, 5 };
int total = 0;
foreach (int value in values)
{
if (value < 0)
{
continue;
}
total += value;
}
Console.WriteLine(total);
}
}
Output:
12
Skipping the Update in a While Loop
int i = 0;
while (i < 5)
{
if (i == 2)
{
continue;
}
Console.WriteLine(i);
i++;
}
This code compiles, but it can run forever. When i becomes 2, continue jumps back to the condition before i++ runs, so i remains 2.
using System;
class Program
{
static void Main()
{
int i = 0;
while (i < 5)
{
i++;
if (i == 3)
{
continue;
}
Console.WriteLine(i);
}
}
}
Output:
1
2
4
5
Best Practices
- Use
breakwhen the loop’s job is complete and later iterations cannot change the answer. - Use
continuefor guard clauses near the top of a loop, such as invalid input, disabled items, or records that do not match a filter. - Keep the reason for a jump obvious. If a loop has many
breakandcontinuestatements, consider splitting work into smaller methods. - Remember that jumps affect only the nearest loop. For multi-level exits, prefer a helper method with
returnor a clearly named flag. - Be extra careful with
continueinwhileloops. Perform required updates before the jump can occur. - Do not use
breakto hide a poorly chosen loop condition. When the stopping rule is simple, put it directly in the loop condition. - Prefer readable loop bodies over clever control flow. A small
continuecan reduce nesting; too many jumps can obscure the path.
Practice Exercises
- Create an array of product prices. Use
continueto skip prices less than or equal to zero, then print the total of the valid prices. - Write a loop that searches an array of names for
"Mina". Usebreakas soon as the name is found, then print whether it was found. - Use nested loops to scan a small seating chart. Print the first open seat in each row, then use
breakto move to the next row.
Summary
breakexits the nearest loop orswitchimmediately.continueskips the rest of the current loop iteration and moves toward the next one.- In nested loops, both statements apply only to the innermost loop that contains them.
continuein aforloop still runs the iterator; in awhileloop it jumps straight to the condition check.- The compiler emits branch instructions for these statements, so they are runtime control flow, not exceptions.
- Use them to make loop intent clearer, but avoid piling up jumps that make the loop difficult to trace.
