C# 15 наконец избавляет вложенные циклы от флагов и `goto`
break и continue могут указывать метку внешнего цикла. Это позволяет сразу выйти из нескольких уровней вложенности или перейти к следующей итерации нужного цикла.
outer: for (int row = 0; row < grid.Height; row++)
{
for (int column = 0; column < grid.Width; column++)
{
if (grid[row, column].IsBlocked)
{
continue outer;
}
if (grid[row, column].IsGoal)
{
break outer;
}
}
}
Здесь:
- continue outer прекращает внутренний цикл и запускает следующую итерацию внешнего;
- break outer полностью выходит из обоих циклов.
Раньше для такого поведения приходилось использовать булевы флаги, дополнительные проверки или goto.
В C# 15 этот код можно записать короче и понятнее.
Особенно удобно при обходе:
- матриц;
- вложенных коллекций;
- игровых карт;
- таблиц;
- сложных структур данных.
Небольшое изменение, которое убирает много лишнего кода из вложенных циклов.
break и continue могут указывать метку внешнего цикла. Это позволяет сразу выйти из нескольких уровней вложенности или перейти к следующей итерации нужного цикла.
outer: for (int row = 0; row < grid.Height; row++)
{
for (int column = 0; column < grid.Width; column++)
{
if (grid[row, column].IsBlocked)
{
continue outer;
}
if (grid[row, column].IsGoal)
{
break outer;
}
}
}
Здесь:
- continue outer прекращает внутренний цикл и запускает следующую итерацию внешнего;
- break outer полностью выходит из обоих циклов.
Раньше для такого поведения приходилось использовать булевы флаги, дополнительные проверки или goto.
В C# 15 этот код можно записать короче и понятнее.
Особенно удобно при обходе:
- матриц;
- вложенных коллекций;
- игровых карт;
- таблиц;
- сложных структур данных.
Небольшое изменение, которое убирает много лишнего кода из вложенных циклов.