Interruzione / uscita annidata per in vb.net


122

Come posso uscire da annidato for o loop in vb.net?

Ho provato a usare exit for ma è saltato o interrotto solo un ciclo for.

Come posso farlo per quanto segue:

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

Ciò di cui ha veramente bisogno VB è una Exit For itemvariante dell'istruzione, simile a Next item. Nei "bei vecchi tempi" si poteva esplicitamente Nextil ciclo esterno. Oggi VB dà un errore. Certo, è invece più "costruttivo" Exit For.
ysap

Risposte:


199

Sfortunatamente, non exit two levels of forci sono dichiarazioni, ma ci sono alcune soluzioni alternative per fare quello che vuoi:

  • Goto . In generale, l'uso gotoè considerato una cattiva pratica (e giustamente), ma l'uso gotosolo per un salto in avanti dalle istruzioni di controllo strutturato è generalmente considerato OK, specialmente se l'alternativa è avere un codice più complicato.

    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:
  • Blocco esterno fittizio

    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

    o

    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
  • Funzione separata : inserire i loop all'interno di una funzione separata, dalla quale è possibile uscire con return. Ciò potrebbe richiedere il passaggio di molti parametri, tuttavia, a seconda di quante variabili locali si utilizzano all'interno del ciclo. Un'alternativa sarebbe mettere il blocco in un lambda multilinea, poiché questo creerà una chiusura sulle variabili locali.

  • Variabile booleana : questo potrebbe rendere il tuo codice un po 'meno leggibile, a seconda di quanti livelli di loop nidificati hai:

    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
Non posso dire che qualcuno di questi sia migliore gotodell'altro rispetto alla funzione se effettivamente ha senso.
Chris Marisic

2
Lo userò gotoin un grande progetto solo per ricordare i miei giorni di programmazione in qbasic, ah tempi così innocenti. altrimenti andrei per un manichino.
Sharky

1
Preferisco l' approccio Try/ Exit Try, ma non sono un fan gotodell'opzione.
JohnH

Tieni presente che il metodo "variabile booleana" richiede più variabili e test man mano che il livello di annidamento diventa più profondo. Questo diventa
fugace

1
@ysap - Nella mia esperienza, è raro che siano necessarie più variabili booleane. Tipicamente, esiste una singola condizione di uscita (ad esempio "fatto") che una volta incontrata, tutti i livelli del ciclo dovrebbero essere chiusi. Tuttavia, preferisco creare un metodo separato e utilizzare "Return" - questo incapsula in modo pulito il costrutto annidato.
ToolmakerSteve

16

Metti i loop in una subroutine e chiama return


1
Vale la pena notare che esiste un sovraccarico associato a tale chiamata che non è presente nella gotosoluzione più semplice . Ovviamente, se il codice è riutilizzabile, dovrebbe comunque essere già in una funzione.
Dan Bechard

Come può essere un sovraccarico? @Dan
Altiano Gerung

@AltianoGerung Bene, il mio commento sopra presume che il compilatore non ottimizzi e incorpori la chiamata di funzione. Tutte le chiamate di funzione (supponendo che non siano inline dal compilatore) hanno l'overhead del prologo e dell'epilogo per aggiornare il puntatore dello stack di base (così come fare altre cose come chiamare distruttori e fare garbage collection se il linguaggio lo supporta). Questa è spesso una minuzia nel grande schema delle cose, ma esiste e può diventare rapidamente evidente in anelli stretti. en.wikipedia.org/wiki/Function_prologue
Dan Bechard

@ Dan Beh, questo è al di là di me LOL. Penso che con i miei casi d'uso e come la tecnologia migliora nel tempo, non dovrò mai preoccuparmene.
Altiano Gerung

2
@AltianoGerung Se c'è qualcosa che l'esperienza mi ha insegnato, è che con una scala sufficiente, anche il più piccolo dei problemi diventa abbastanza grande da avere importanza. Come sempre, profilo prima di fare qualsiasi ipotesi. :)
Dan Bechard

3

Rendi il ciclo esterno un ciclo while e "Exit While" nell'istruzione if.


Questo fa esattamente la stessa cosa che gotocon più istruzioni, più verbosità e più rientro. Qual e il punto?
Dan Bechard

3

Ho provato a digitare "exit for" un paio di volte e ho notato che funzionava e VB non mi ha urlato contro. Immagino sia un'opzione, ma sembrava brutta.

Penso che l'opzione migliore sia simile a quella condivisa da Tobias. Metti il ​​tuo codice in una funzione e fallo tornare quando vuoi uscire dai tuoi loop. Sembra anche più pulito.

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

No, più "Esci per" non producono il comportamento desiderato. Il primo esce dal primo ciclo, quelli aggiuntivi non vengono mai raggiunti, quindi non hanno effetto. Oltre a questo suggerimento, sembra che tu abbia semplicemente ripetuto le risposte precedenti.
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

Non usare questo. Il suo comportamento è sbagliato. Vedere invece la soluzione "variabile booleana" della risposta accettata di sei anni prima. Se fosse un nuovo approccio, spiegherei cosa lo fa comportare in modo errato, ma non vale la pena farlo, poiché l'approccio è già stato correttamente mostrato in quella risposta precedente.
ToolmakerSteve

0

Se voglio uscire da un ciclo for-to, imposto l'indice oltre il limite:

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

Poppa.


Consiglio di mostrare come questo si applica a questa domanda. Prendi il codice dalla domanda e modificalo per utilizzare questo approccio.
ToolmakerSteve
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.