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 break cannot appear by itself in the middle of a method unless it is inside a loop or switch.
  • Use braces around the related if body so the jump belongs to the condition you intended.
  • In while loops, update counters or input values before a possible continue, 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

  1. The compiler parses break; or continue; and verifies that the statement is inside a loop, or for break, inside a loop or switch.
  2. For break, the compiler chooses the instruction just after the nearest enclosing loop as the jump target.
  3. For continue, the compiler chooses the next-iteration target: the iterator step for for, the condition check for while, or the enumerator advance for foreach.
  4. At runtime, when execution reaches the jump statement, the CLR branches to that target instead of running the remaining statements in sequence.
  5. If the loop is inside a try block with a finally, the finally code 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 break when the loop’s job is complete and later iterations cannot change the answer.
  • Use continue for 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 break and continue statements, consider splitting work into smaller methods.
  • Remember that jumps affect only the nearest loop. For multi-level exits, prefer a helper method with return or a clearly named flag.
  • Be extra careful with continue in while loops. Perform required updates before the jump can occur.
  • Do not use break to 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 continue can reduce nesting; too many jumps can obscure the path.

Practice Exercises

  1. Create an array of product prices. Use continue to skip prices less than or equal to zero, then print the total of the valid prices.
  2. Write a loop that searches an array of names for "Mina". Use break as soon as the name is found, then print whether it was found.
  3. Use nested loops to scan a small seating chart. Print the first open seat in each row, then use break to move to the next row.

Summary

  • break exits the nearest loop or switch immediately.
  • continue skips 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.
  • continue in a for loop still runs the iterator; in a while loop 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.