Подтвердить что ты не робот

Выйти из нескольких циклов?

Возможный дубликат:
Вывод из вложенного цикла

У меня есть этот код

foreach (___)
{
    foreach (___)
    {
        foreach (___)
        {
            if (condition)
            {
                //break out of all loops
            }
        }
    }
}

Но break только "разбивает" самый внутренний цикл (извините за мой английский), и я хочу оставить их всех...

Я думал о:

  • GOTO, но мне всегда говорили не использовать его
  • Тип булевого флага

Есть ли более элегантный способ? как предоставлено С#?

Заранее благодарим за помощь!

4b9b3361

Ответ 1

Очень элегантным решением является перемещение всего гнезда петель на отдельный метод и return;, когда вы хотите вырваться из всех циклов.

Ответ 2

A goto отлично здесь:

foreach (___)
{
    foreach (___)
    {
        if (condition)
        {
            goto done;
        }
    }
}
done: ;

Ответ 3

Лучший способ, вероятно, состоит в том, чтобы реорганизовать более мелкие методы с помощью операторов return. Но если вам нужно много переменных в области видимости, вы всегда можете использовать делегат.

   Action work = delegate
        {
            foreach (___)
            {
                 foreach (___)
                 {
                       foreach (___)
                       {
                            if (condition)
                            {
                                 return;
                            }
                       }
                  }
             }

        };

  work();

Ответ 4

Несколько лет назад, когда я учился в школе, у нас была информатика с красивой книгой, глупый учитель. Одно правило - "нет". У меня был алгоритм с множеством циклов, который рос во много раз больше без goto.

Есть веские причины, и вырывание из нескольких циклов - это одно.

Ответ 5

Возможно, это единственная действительная причина использования goto.

Ответ 6

bool bLoopBreak = false;

foreach (___)
{
    foreach (___)
    {
        foreach (___)
        {
            if (condition)
            {
                bLoopBreak = true;
                break;
                //break out of all loops
            }
        }
        if (bLoopBreak) break;
    }
    if (bLoopBreak) break;
}

Ответ 7

Не бойтесь использовать goto в таком случае. break и continue являются просто синтаксическим сахаром для goto, и он экономно и правильно комментирует, что он может сделать код более понятным, чем множество вложенных проверок, чтобы увидеть, следует ли останавливать цикл.

Ответ 8

PHP позволяет это сделать:

foreach (___)
{
    foreach (___)
    {
        foreach (___)
        {
            break 3; // get out of all 3 loops
        }
    }
}

Я не очень много знаю о С#, но у него может быть аналогичная функция.

Ответ 9

Просто, чтобы бросить альтернативу там: вы также можете выбросить исключение внутри цикла. В С#/Java/Python это разумно дешево. (В С++ не так много.)

Обратите внимание, что у Python есть исключение StopIteration для аналогичного случая, так что это не неслыханно, хотя это может быть немного неортодоксальным в С# -land.;)

Иногда вы получаете исключение бесплатно, и поэтому его можно использовать, но лучше документировать его, если вы принимаете этот подход.

try {
    foreach (___) {
        foreach (___) {
            if(your condition true)  {
                throw new IterationDone(); // or use a singleton to avoid allocating
            }
        }
    }
    // not found
catch (IterationDone e) {
    // yay    
}

Я сделал ответ на wiki сообщества, чтобы его можно было увидеть и обсудить. (Я не выступаю за это как первое и лучшее решение, это просто решение и, следовательно, заслуживает того, чтобы быть здесь...)