Порушення / вихід вкладений в vb.net


122

Як я можу вийти з вкладеного для або в циклі на vb.net?

Я спробував використовувати вихід для, але він стрибнув або зламав лише один лише для циклу.

Як зробити це для наступного:

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

Відповіді:


199

На жаль, exit two levels of forзаяв немає , але є кілька способів вирішити те, що ви хочете:

  • Гото . Загалом, використовуючи 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, ах такі невинні часи. інакше я б пішов на манекен.
Шаркі

1
Я віддаю перевагу Try/ Exit Tryпідходу, але я не шанувальник цього gotoваріанту.
JohnH

Зауважте, що метод "булева змінна" вимагає декількох змінних і тестів, оскільки рівень вкладення стає все глибшим. Це стає
пустотливим

1
@ysap - На мій досвід, рідко потрібні кілька булевих змінних. Зазвичай існує одна умова виходу (наприклад, "виконано"), що після її зустрічі всі рівні циклу повинні бути закриті. Тим не менш, я вважаю за краще зробити окремий метод, а використовувати "Return" - це чітко інкапсулює вкладену конструкцію.
ToolmakerSteve

16

Покладіть петлі в підпрограму і зателефонуйте return


1
Варто зауважити, що з таким дзвінком пов'язані накладні витрати, які відсутні у більш простому gotoрішенні. Звичайно, якщо код є багаторазовим, він все одно повинен бути у функції.
Ден Бешард

Як це може бути накладними? @Dan
Altiano Gerung

@AltianoGerung Ну, мій коментар вище передбачає, що компілятор не оптимізує та вбудовує виклик функції. Усі виклики функцій (якщо припустити, що компілятор їх не накреслив) мають накладні витрати на пролог та епілог для оновлення покажчика базового стеку (як і інші речі, такі як деструктори викликів та збирання сміття, якщо мова це підтримує). Це часто є дрібницею в грандіозній схемі речей, але вона існує і може швидко стати очевидною в тісних петлях. en.wikipedia.org/wiki/Function_prologue
Дан Бешард

@Dan Ну, це поза мене ЛОЛ. Я думаю, що з моїми випадками використання і з тим, як технологія вдосконалюється з часом, мені ніколи не доведеться турбуватися про це.
Altiano Gerung

2
@AltianoGerung Якщо мене чогось досвіду навчив, то з достатньою мірою масштабність навіть найменших проблем стає достатньо важливою. Як завжди, профілюйте перед тим, як робити будь-які припущення. :)
Ден Бешард

3

Зробіть зовнішню петлю циклом час і "Вихід під час" в операторі if.


Це робиться точно так само, як gotoі більше інструкцій, більше багатослівностей і більше відступів. В чому справа?
Ден Бешард

3

Я кілька разів експериментував із набором "виходу" і помітив, що він спрацював, і VB не кричав на мене. Я думаю, це варіант, але він виглядав просто погано.

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

For Each item In itemlist
    For Each item1 In itemlist1
        If item1 = item Then
            Return item1
        End If
    Next
Next

Ні, кілька разів "Вихід для" не призводить до бажаної поведінки. Перший виходить з першого циклу, додаткові ніколи не дістаються, тому не мають ефекту. Крім цієї пропозиції, ви, схоже, просто повторили попередні відповіді.
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.