Breaking / Exit verschachtelt in vb.net


122

Wie komme ich aus verschachtelten oder Schleifen in vb.net heraus?

Ich habe versucht, exit für zu verwenden, aber es ist nur eine for-Schleife gesprungen oder gebrochen.

Wie kann ich es für Folgendes machen:

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

Was VB wirklich braucht, ist eine Exit For itemVariante der Aussage, ähnlich wie Next item. In den "guten alten Zeiten" konnte man explizit Nextdie äußere Schleife. Heute gibt VB einen Fehler aus. Natürlich ist es Exit Forstattdessen "konstruktiver" .
Ysap

Antworten:


199

Leider gibt es keine exit two levels of forAussage, aber es gibt einige Problemumgehungen, um das zu tun, was Sie wollen:

  • Gehe zu . Im allgemeinen Verwendung gotowird als schlechte Praxis sein (und das zu Recht), wobei jedoch gotonur für ein vorwärts springen aus strukturierten Steueranweisungen ist in der Regel in Ordnung zu sein betrachtet, vor allem , wenn die Alternative mehr komplizierten Code haben.

    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:
  • Dummy Außenblock

    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

    oder

    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
  • Separate Funktion : Platzieren Sie die Schleifen in einer separaten Funktion, mit der Sie beendet werden können return. Dies kann jedoch erfordern, dass Sie viele Parameter übergeben, je nachdem, wie viele lokale Variablen Sie in der Schleife verwenden. Eine Alternative wäre, den Block in ein mehrzeiliges Lambda zu setzen, da dies einen Abschluss über die lokalen Variablen erzeugt.

  • Boolesche Variable : Dies kann dazu führen, dass Ihr Code etwas weniger lesbar ist, je nachdem, wie viele Ebenen verschachtelter Schleifen Sie haben:

    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
Ich kann nicht sagen, dass eines davon besser ist als das gotoandere als die Funktion, wenn es tatsächlich Sinn macht.
Chris Marisic

2
Ich werde das gotoin einem großen Projekt verwenden, um mich an meine Programmiertage in qbasic zu erinnern, ah so unschuldige Zeiten. sonst würde ich mich für einen Dummy entscheiden.
Sharky

1
Ich bevorzuge den Try/ Exit Try-Ansatz, aber ich bin kein Fan der gotoOption.
JohnH

Beachten Sie, dass die Methode "Boolesche Variable" mehrere Variablen und Tests erfordert, wenn die Verschachtelungsebene tiefer wird. Dies wird flüchtig ...
ysap

1
@ysap - Nach meiner Erfahrung sind selten mehrere boolesche Variablen erforderlich. In der Regel gibt es eine einzelne Beendigungsbedingung (z. B. "erledigt"), bei der alle Schleifenebenen beendet werden sollten, sobald sie auftreten. Trotzdem ziehe ich es vor, eine separate Methode zu erstellen und "Return" zu verwenden - dies kapselt das verschachtelte Konstrukt sauber.
ToolmakerSteve

16

Setzen Sie die Schleifen in ein Unterprogramm und rufen Sie auf return


1
Es ist erwähnenswert, dass mit einem solchen Anruf ein Overhead verbunden ist, der in der einfacheren gotoLösung nicht vorhanden ist . Wenn der Code wiederverwendbar ist, sollte er natürlich ohnehin schon in einer Funktion sein.
Dan Bechard

Wie kann es ein Overhead sein? @ Dan
Altiano Gerung

@AltianoGerung Nun, mein Kommentar oben geht davon aus, dass der Compiler den Funktionsaufruf nicht optimiert und inline macht. Alle Funktionsaufrufe (vorausgesetzt, sie werden nicht vom Compiler eingebunden) haben den Overhead von Prolog und Epilog, um den Basisstapelzeiger zu aktualisieren (sowie andere Dinge wie Aufrufdestruktoren und Garbage Collection, wenn die Sprache dies unterstützt). Dies ist oft eine Kleinigkeit im großen Schema der Dinge, existiert jedoch und kann sich in engen Schleifen schnell bemerkbar machen. en.wikipedia.org/wiki/Function_prologue
Dan Bechard

@ Dan Nun, das ist mir ein Rätsel LOL. Ich denke, mit meinen Anwendungsfällen und der Verbesserung der Technologie im Laufe der Zeit muss ich mir keine Sorgen machen.
Altiano Gerung

2
@AltianoGerung Wenn mich etwas gelehrt hat, ist es so, dass mit genügend Skalierung selbst kleinste Probleme groß genug werden, um eine Rolle zu spielen. Profilieren Sie wie immer, bevor Sie Annahmen treffen. :)
Dan Bechard

3

Machen Sie die äußere Schleife zu einer while-Schleife und "Exit While" in der if-Anweisung.


Dies macht genau das Gleiche wie gotomit mehr Anweisungen, mehr Ausführlichkeit und mehr Einrückung. Was ist der Punkt?
Dan Bechard

3

Ich habe ein paar Mal mit der Eingabe von "exit for" experimentiert und festgestellt, dass es funktioniert hat und VB mich nicht angeschrien hat. Es ist eine Option, aber es sah einfach schlecht aus.

Ich denke, die beste Option ähnelt der von Tobias. Fügen Sie einfach Ihren Code in eine Funktion ein und lassen Sie ihn zurückgeben, wenn Sie aus Ihren Schleifen ausbrechen möchten. Sieht auch sauberer aus.

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

Nein, mehrere "Exit For" führen nicht zum gewünschten Verhalten. Der erste verlässt die erste Schleife, zusätzliche werden nie erreicht, haben also keine Auswirkung. Abgesehen von diesem Vorschlag scheinen Sie einfach frühere Antworten wiederholt zu haben.
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

Verwenden Sie dies nicht. Sein Verhalten ist falsch. Sehen Sie sich stattdessen die "boolesche Variable" -Lösung der akzeptierten Antwort von sechs Jahren zuvor an. Wenn es ein neuer Ansatz wäre, würde ich erklären, warum es sich falsch verhält, aber es lohnt sich nicht, dies zu tun, da der Ansatz in dieser früheren Antwort bereits korrekt gezeigt wurde.
ToolmakerSteve

0

Wenn ich eine for-to-Schleife beenden möchte, setze ich den Index einfach über das Limit hinaus:

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

Poppa.


Ich empfehle zu zeigen, wie dies auf diese Frage zutrifft. Nehmen Sie den Code aus der Frage und bearbeiten Sie ihn, um diesen Ansatz zu verwenden.
ToolmakerSteve
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.