Взлом / выход вложен в 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

Что действительно нужно 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

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

Нет, несколько "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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.