break and continue only ever affected the innermost loop. To steer out of nested loops you needed a Boolean flag checked at every level or a goto to jump past them.
C# 15 lets break and continue name a label on an enclosing loop (or break on a switch) so the jump goes exactly where you mean.
Code
csharp
outer: for (int row = 0; row < grid.Height; row++)
{
for (int column = 0; column < grid.Width; column++)
{
if (grid[row, column].IsBlocked)
{
continue outer; // Abandon this row, start the next
}
if (grid[row, column].IsGoal)
{
break outer; // Leave both loops
}
}
}csharp
bool found = false;
for (int row = 0; row < grid.Height && !found; row++)
{
for (int column = 0; column < grid.Width; column++)
{
if (grid[row, column].IsBlocked)
{
break; // Abandon this row, start the next
}
if (grid[row, column].IsGoal)
{
found = true;
break; // Only leaves the inner loop, the flag stops the outer
}
}
}csharp
for (int row = 0; row < grid.Height; row++)
{
for (int column = 0; column < grid.Width; column++)
{
if (grid[row, column].IsBlocked)
{
goto nextRow;
}
if (grid[row, column].IsGoal)
{
goto done;
}
}
nextRow:;
}
done:;Notes
- Place the label directly on the loop or
switchit identifies. With stacked labels such asa: b: while, onlyblabels the loop continuecan only target a loop, so a labeledswitchcan be the target ofbreakbut notcontinue- Without a label
breakandcontinuebehave as before and target the innermost applicable statement - The IDE0410 style rule flags flag and
gotopatterns that a labeled jump can replace