Question
In a C# loop, what is the difference between break and continue when a condition becomes true? Specifically, how does each statement affect the current loop and its next iteration?
foreach (DataRow row in myTable.Rows)
{
if (someConditionEvalsToTrue)
{
break;
// Or: continue;
}
}
Short Answer
break stops the entire nearest loop immediately. continue skips the rest of the current iteration and starts the next iteration, if one exists. This page explains when to use each statement safely in C#.
Concept
A loop repeats a block of code for multiple values, such as every row in a table. Sometimes a program needs to change that normal flow:
- Use
breakwhen the loop has finished its job and should stop completely. - Use
continuewhen the current item should be ignored but later items may still matter.
In a foreach loop, break exits the foreach statement. Execution resumes at the first statement after the loop.
continue does not leave the loop. It skips any remaining statements in the current loop body and moves to the next item in the collection.
These statements matter because they make searches, filtering, validation, and data-processing code clearer. They can also avoid unnecessary work—for example, stopping as soon as a required record is found.
Mental Model
Imagine checking books on a shelf:
breakmeans: “I found the book I need. Stop checking shelves and leave the library aisle.”continuemeans: “This book is not relevant. Skip it and check the next book.”
break ends the task. continue rejects one item while keeping the task going.
Syntax and Examples
The basic syntax is:
foreach (DataRow row in myTable.Rows)
{
if (condition)
{
break; // Exit the loop entirely
// continue; // Skip this item and process the next one
}
}
break: stop after finding a match
int[] scores = { 55, 72, 90, 61 };
foreach (int score in scores)
{
if (score >= 90)
{
Console.WriteLine("Excellent score found.");
break;
}
Console.WriteLine($"Checked: {score}");
}
Console.WriteLine("Finished checking scores.");
Output:
Checked: 55
Checked: 72
Excellent score found.
Finished checking scores.
When 90 is found, break exits the loop. The value 61 is never checked.
continue: skip unwanted values
int[] scores = { 55, -1, 72, -1, 90 };
foreach (int score in scores)
{
if (score < 0)
{
continue;
}
Console.WriteLine($"Valid score: {score}");
}
Output:
Valid score: 55
Valid score: 72
Valid score: 90
For each -1, continue skips Console.WriteLine and proceeds to the next value.
Step by Step Execution
Consider this code:
int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
if (number == 3)
{
continue;
}
if (number == 5)
{
break;
}
Console.WriteLine(number);
}
Console.WriteLine("Loop ended.");
Execution trace:
numberis1.- It is not
3or5. 1is printed.
- It is not
numberis2.- It is not
3or5. 2is printed.
- It is not
numberis3.- The first condition is true.
continueskips the rest of this iteration.- Nothing is printed for
3.
numberis4.- It is not
3or5. 4is printed.
- It is not
numberis5.- The second condition is true.
breakexits theforeachloop immediately.
- The statement after the loop runs.
Output:
1
2
4
Loop ended.
Real World Use Cases
Stop searching after a match
Use break when only the first matching item is needed.
DataRow? matchingRow = null;
foreach (DataRow row in myTable.Rows)
{
if (row.Field<int>("Id") == requestedId)
{
matchingRow = row;
break;
}
}
Ignore incomplete data rows
Use continue when invalid rows should not prevent later rows from being processed.
foreach (DataRow row in myTable.Rows)
{
if (row.IsNull("Email"))
{
continue;
}
SendEmail(row.Field<string>("Email")!);
}
Stop reading a file at an end marker
foreach (string line in File.ReadLines("report.txt"))
{
if (line == "END")
{
break;
}
ProcessLine(line);
}
Skip comments or blank lines in imported text
foreach (string line in File.ReadLines("settings.txt"))
{
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#"))
{
continue;
}
LoadSetting(line);
}
Real Codebase Usage
In production code, break and continue are usually used to make loop intent explicit.
Search loops often use break
A loop that searches for one item can stop as soon as it succeeds:
User? foundUser = null;
foreach (User user in users)
{
if (user.Id == userId)
{
foundUser = user;
break;
}
}
In many C# codebases, this can also be expressed with LINQ when it improves readability:
User? foundUser = users.FirstOrDefault(user => user.Id == userId);
Data-processing loops often use continue
A common pattern is a guard clause near the top of the loop. It removes invalid or irrelevant items early, keeping the main work less nested.
foreach (Order order in orders)
{
if (order.IsCancelled)
{
continue;
}
if (order.Total <= 0)
{
continue;
}
invoiceService.CreateInvoice(order);
}
Important design guideline
Use these statements when they make control flow easier to read. If a loop has many break and continue paths, consider extracting part of the work into a method with a clear name, such as ShouldProcessOrder or TryParseRecord.
Common Mistakes
Expecting continue to exit the loop
This code still processes later numbers:
foreach (int number in numbers)
{
if (number == 3)
{
continue;
}
Console.WriteLine(number);
}
Use break instead if finding 3 should end the loop.
Expecting break to skip only one item
foreach (int number in numbers)
{
if (number < 0)
{
break; // Stops processing all remaining numbers.
}
Process(number);
}
If negative values should be ignored rather than end processing, use continue.
foreach (int number in numbers)
{
if (number < 0)
{
continue;
}
Process(number);
}
Writing code after break or continue in the same block
The following code is unreachable and causes a compiler error:
if (isComplete)
{
break;
Console.WriteLine("This cannot run");
}
Both statements immediately transfer control elsewhere, so put required work before them.
Assuming break exits every nested loop
break exits only the nearest enclosing loop or switch statement.
for (int row = 0; row < 3; row++)
{
for (int column = 0; column < 3; column++)
{
if (column == 1)
{
break;
}
}
Console.WriteLine($"Finished row {row}");
}
The inner loop stops at column 1, but the outer loop continues with later rows.
Creating an infinite while loop with continue
In a while loop, make sure the value controlling the condition is updated before continue when necessary.
Broken example:
int number = 0;
while (number < 5)
{
if (number == 2)
{
continue;
}
number++;
}
When number becomes 2, it never increments again. Move the increment before continue or restructure the loop.
Comparisons
| Statement | What it does | Does the loop continue? | Typical use |
|---|---|---|---|
break | Immediately exits the nearest loop or switch | No | Stop after finding a result or reaching an end condition |
continue | Skips the remaining code in the current iteration | Yes | Ignore invalid, empty, or irrelevant items |
return | Immediately exits the current method | No, because the method ends | Finish a method when a result or error condition is reached |
break versus return
foreach (int number in numbers)
{
if (number == 0)
{
break;
}
}
Console.WriteLine("This still runs after break.");
With return, the method ends, so code after the loop does not run:
foreach (int number in numbers)
{
if (number == 0)
{
return;
}
}
Console.WriteLine("This does not run if zero is found.");
continue versus an if block
Both approaches can be valid:
foreach (int number in numbers)
{
if (number >= 0)
{
Process(number);
}
}
foreach (int number in numbers)
{
if (number < 0)
{
continue;
}
Process(number);
}
continue is often clearer when the main processing block is longer, because it avoids wrapping that block in another level of indentation.
Cheat Sheet
break; // Leave the nearest loop immediately.
continue; // Skip the current iteration; begin the next iteration.
return; // Leave the entire current method.
| Need | Use |
|---|---|
| Stop processing all remaining items | break |
| Ignore one item and process later items | continue |
| End the current method completely | return |
Key rules:
breakandcontinuework in loops such asfor,foreach,while, anddo.breakexits only the nearest nested loop.continueskips statements below it in the current iteration.- Code placed after an unconditional
breakorcontinuein the same block is unreachable. - In a
whileloop, ensurecontinuedoes not accidentally skip the update that eventually ends the loop.
FAQ
Does break exit a foreach loop in C#?
Yes. break immediately exits the nearest foreach loop. Execution continues after that loop.
Does continue exit a C# loop?
No. continue exits only the current iteration. The loop then moves to its next iteration if there is one.
What happens when continue is used in a foreach loop?
C# stops executing the rest of the loop body for the current item and retrieves the next item from the collection.
Can I use break inside nested loops?
Yes, but it exits only the innermost loop containing that break. It does not automatically exit outer loops.
Should I use break when I find the first matching item?
Usually, yes, if you do not need to inspect later items. This avoids unnecessary processing.
Is continue bad practice?
No. It is useful for skipping invalid or irrelevant data. Avoid it only when it makes already-complex control flow harder to follow.
Can code run after break or continue in the same block?
No. Both statements transfer control immediately, so following statements in that path are unreachable.
Mini Project
Description
Build a console-based order processor. The program will skip orders that cannot be processed and stop processing when it reaches a closing marker. This mirrors importing records from a file, queue, or database result set.
Goal
Process valid orders, skip cancelled orders, and stop when a closing order marker is encountered.
Requirements
Create a list of orders with an order number, total, and cancellation status.
Use continue to skip cancelled orders.
Use continue to skip orders whose total is zero or less.
Use break when the order number is "CLOSE".
Print each processed order and a final completion message.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
Best Way to Repeat a Character in C#: Building Repeated Strings Efficiently
Learn the best way to repeat a character in C#, compare StringBuilder, string concatenation, and simpler built-in options.
C# Access Modifiers and static: public, private, protected, and Defaults
Learn how C# public, private, protected, and default access control visibility, and how static differs from instance members.