Question

C# break vs continue in Loops: Differences and Examples

csharploopsbreakenumerationcontinue

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 break when the loop has finished its job and should stop completely.
  • Use continue when 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:

  • break means: “I found the book I need. Stop checking shelves and leave the library aisle.”
  • continue means: “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.

Take Quiz

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:

  1. number is 1.
    • It is not 3 or 5.
    • 1 is printed.
  2. number is 2.
    • It is not 3 or 5.
    • 2 is printed.
  3. number is 3.
    • The first condition is true.
    • continue skips the rest of this iteration.
    • Nothing is printed for 3.
  4. number is 4.
    • It is not 3 or 5.
    • 4 is printed.
  5. number is 5.
    • The second condition is true.
    • break exits the foreach loop immediately.
  6. 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);
}
Take Quiz

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

StatementWhat it doesDoes the loop continue?Typical use
breakImmediately exits the nearest loop or switchNoStop after finding a result or reaching an end condition
continueSkips the remaining code in the current iterationYesIgnore invalid, empty, or irrelevant items
returnImmediately exits the current methodNo, because the method endsFinish 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.

Take Quiz

Cheat Sheet

break;    // Leave the nearest loop immediately.
continue; // Skip the current iteration; begin the next iteration.
return;   // Leave the entire current method.
NeedUse
Stop processing all remaining itemsbreak
Ignore one item and process later itemscontinue
End the current method completelyreturn

Key rules:

  • break and continue work in loops such as for, foreach, while, and do.
  • break exits only the nearest nested loop.
  • continue skips statements below it in the current iteration.
  • Code placed after an unconditional break or continue in the same block is unreachable.
  • In a while loop, ensure continue does 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.

Take Quiz

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.

Take Quiz

Keep learning

Related questions

View more