Взлом / выход вложен в vb.net

122

Как мне выйти из вложенного цикла или цикла в vb.net?

Я попытался использовать exit for, но он прыгнул или сломал только один цикл for.

Как я могу это сделать для следующего:

for each item in itemList
     for each item1 in itemList1
          if item1.text = "bla bla bla" then
                exit for
          end if
     end for
end for
KoolKabin
источник
Что действительно нужно VB, так это Exit For itemвариант оператора, похожий на Next item. В «старые добрые времена» вы могли явно Nextиспользовать внешний цикл. Сегодня VB выдает ошибку. Конечно, это более «конструктивно» Exit For.
ysap 07

Ответы:

199

К сожалению, здесь нет exit two levels of forинструкции, но есть несколько обходных путей, чтобы сделать то, что вы хотите:

  • Goto . В общем, используя gotoэто считается плохой практикой (и справедливо), но с использованием gotoисключительно вперед выскочить из структурированных управляющих операторов, как правило , считается ОК, особенно если альтернативой является более сложный код.

    For Each item In itemList
        For Each item1 In itemList1
            If item1.Text = "bla bla bla" Then
                Goto end_of_for
            End If
        Next
    Next
    
    end_of_for:
  • Пустой внешний блок

    Do
        For Each item In itemList
            For Each item1 In itemList1
                If item1.Text = "bla bla bla" Then
                    Exit Do
                End If
            Next
        Next
    Loop While False

    или

    Try
        For Each item In itemlist
            For Each item1 In itemlist1
                If item1 = "bla bla bla" Then
                    Exit Try
                End If
            Next
        Next
    Finally
    End Try
  • Отдельная функция : поместите циклы в отдельную функцию, из которой можно выйти с помощью return. Однако для этого может потребоваться передать множество параметров, в зависимости от того, сколько локальных переменных вы используете внутри цикла. Альтернативой было бы поместить блок в многострочную лямбду, поскольку это создаст замыкание для локальных переменных.

  • Логическая переменная : это может сделать ваш код менее читабельным, в зависимости от того, сколько у вас слоев вложенных циклов:

    Dim done = False
    
    For Each item In itemList
        For Each item1 In itemList1
            If item1.Text = "bla bla bla" Then
                done = True
                Exit For
            End If
        Next
        If done Then Exit For
    Next
Heinzi
источник
3
Нельзя сказать, что любой из них лучше, чем gotoдругой, чем функция, если это действительно имеет смысл.
Крис Марисич
2
Я собираюсь использовать это gotoв большом проекте, просто чтобы вспомнить дни программирования на qbasic, такие невинные времена. В противном случае я бы пошел на манекен.
Sharky
1
Я предпочитаю подход Try/ Exit Try, но я не фанат этого gotoварианта.
JohnH
Обратите внимание, что метод «логической переменной» требует нескольких переменных и тестов по мере того, как уровень вложенности становится глубже. Это становится фугасным ...
ysap 07
1
@ysap - По моему опыту, редко требуется несколько логических переменных. Как правило, существует единственное условие выхода (например, «выполнено»), при котором, как только оно встречается, все уровни цикла должны быть завершены. Тем не менее, я предпочитаю создавать отдельный метод и использовать «Return» - это чисто инкапсулирует вложенную конструкцию.
ToolmakerSteve
16

Поместите циклы в подпрограмму и вызовите return

Тобиас Шитковски
источник
1
Стоит отметить, что с таким вызовом связаны накладные расходы, которых нет в более простом gotoрешении. Конечно, если код можно использовать повторно, он в любом случае уже должен быть в функции.
Дэн Бечард
Как это могут быть накладные расходы? @Dan
Альтиано Герунг
@AltianoGerung Ну, мой комментарий выше предполагает, что компилятор не оптимизирует и не встраивает вызов функции. Все вызовы функций (при условии, что они не встроены компилятором) имеют накладные расходы на пролог и эпилог для обновления указателя базового стека (а также на другие вещи, такие как вызов деструкторов и сборку мусора, если язык это поддерживает). Это часто является мелочью в общей схеме вещей, но действительно существует и может быстро проявиться в жестких циклах. en.wikipedia.org/wiki/Function_prologue
Дэн Бечард,
@Dan Ну, это вне меня LOL. Я думаю, что с моими вариантами использования и тем, как технологии со временем улучшаются, мне никогда не придется об этом беспокоиться.
Альтиано Герунг
2
@AltianoGerung Если чему-то меня научил, так это тому, что при достаточном масштабе даже самые маленькие проблемы становятся достаточно большими, чтобы иметь значение. Как всегда, сделайте профиль, прежде чем делать какие-либо предположения. :)
Дэн Бечард
3

Сделайте внешний цикл циклом while и «Exit While» в операторе if.

Эндрю Томас
источник
Это делает то же самое, что и gotoс большим количеством инструкций, большей детализацией и большим количеством отступов. В чем смысл?
Дэн Бечард
3

Я несколько раз экспериментировал с вводом «exit for» и заметил, что это работает, и VB не кричал на меня. Думаю, это вариант, но он выглядел плохо.

Я думаю, что лучший вариант аналогичен тому, который предлагает Тобиас. Просто поместите свой код в функцию и верните его, когда захотите выйти из цикла. Тоже выглядит чище.

For Each item In itemlist
    For Each item1 In itemlist1
        If item1 = item Then
            Return item1
        End If
    Next
Next
Cesar
источник
Нет, несколько "Exit For" не приводят к желаемому поведению. Первый выходит из первого цикла, дополнительные никогда не достигаются, поэтому не действуют. Помимо этого предложения, вы, кажется, просто повторили предыдущие ответы.
ToolmakerSteve
3
For i As Integer = 0 To 100
    bool = False
    For j As Integer = 0 To 100
        If check condition Then
            'if condition match
            bool = True
            Exit For 'Continue For
        End If
    Next
    If bool = True Then Continue For
Next
Хитеш Паливал
источник
Не используйте это. Его поведение неправильное. Вместо этого посмотрите принятое решение «логической переменной» от шести лет назад. Если бы это был новый подход, я бы объяснил, что заставляет его вести себя неправильно, но этого не стоит делать, поскольку подход уже был правильно показан в том предыдущем ответе.
ToolmakerSteve
0

Если я хочу выйти из цикла for-to, я просто устанавливаю индекс за пределом:

    For i = 1 To max
        some code
        if this(i) = 25 Then i = max + 1
        some more code...
    Next`

Папп.

Поппа Минтин
источник
Я рекомендую показать, как это применимо к этому вопросу. Возьмите код из вопроса и отредактируйте его, чтобы использовать этот подход.
ToolmakerSteve