Rupture / sortie imbriquée dans vb.net

122

Comment sortir du for imbriqué ou de la boucle dans vb.net?

J'ai essayé d'utiliser exit for mais il n'a sauté ou cassé qu'une seule boucle for.

Comment puis-je le faire pour ce qui suit:

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
la source
Ce dont VB a vraiment besoin, c'est d'une Exit For itemvariante de l'instruction, similaire à Next item. Dans le «bon vieux temps», vous pouviez explicitement Nextla boucle externe. Aujourd'hui, VB donne une erreur. Bien sûr, il est plus «constructif» à la Exit Forplace.
ysap

Réponses:

199

Malheureusement, il n'y a pas de exit two levels of fordéclaration, mais il existe quelques solutions de contournement pour faire ce que vous voulez:

  • Aller . En général, l'utilisation gotoest considérée comme une mauvaise pratique (et à juste titre), mais l'utilisation gotouniquement pour un saut vers l'avant hors des instructions de contrôle structurées est généralement considérée comme acceptable, surtout si l'alternative est d'avoir un code plus compliqué.

    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:
  • Bloc extérieur factice

    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

    ou

    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
  • Fonction séparée : placez les boucles dans une fonction distincte, qui peut être quittée avec return. Cela peut cependant vous obliger à passer de nombreux paramètres, en fonction du nombre de variables locales que vous utilisez dans la boucle. Une alternative serait de placer le bloc dans un lambda multiligne, car cela créera une fermeture sur les variables locales.

  • Variable booléenne : cela peut rendre votre code un peu moins lisible, en fonction du nombre de couches de boucles imbriquées dont vous disposez:

    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
la source
3
Je ne peux pas dire que l'un d'entre eux est meilleur que l' gotoautre que la fonction si cela a vraiment du sens.
Chris Marisic
2
Je vais l'utiliser gotodans un grand projet juste pour me souvenir de mes jours de programmation dans qbasic, ah des temps si innocents. Sinon, j'irais pour un mannequin.
Sharky
1
Je préfère l' approche Try/ Exit Try, mais je ne suis pas fan de l' gotooption.
JohnH
Notez que la méthode "Variable booléenne" nécessite plusieurs variables et tests à mesure que le niveau d'imbrication devient plus profond. Cela devient fugly ...
ysap
1
@ysap - D'après mon expérience, il est rare d'avoir besoin de plusieurs variables booléennes. En règle générale, il existe une seule condition de sortie (par exemple, «terminé») qu'une fois qu'elle est rencontrée, tous les niveaux de boucle doivent être quittés. Néanmoins, je préfère faire une méthode séparée et utiliser "Return" - cela encapsule proprement la construction imbriquée.
ToolmakerSteve
16

Mettez les boucles dans un sous-programme et appelez return

Tobias Schittkowski
la source
1
Il convient de noter qu'il y a une surcharge associée à un tel appel qui n'est pas présente dans la gotosolution plus simple . Bien sûr, si le code est réutilisable, il devrait déjà être dans une fonction de toute façon.
Dan Bechard
Comment cela peut-il être une surcharge? @Dan
Altiano Gerung
@AltianoGerung Eh bien, mon commentaire ci-dessus suppose que le compilateur n'optimise pas et n'intègre pas l'appel de fonction. Tous les appels de fonction (en supposant qu'ils ne sont pas intégrés par le compilateur) ont la surcharge du prologue et de l'épilogue pour mettre à jour le pointeur de la pile de base (ainsi que pour faire d'autres choses comme appeler des destructeurs et faire un ramasse-miettes si le langage le prend en charge). C'est souvent une minutie dans le grand schéma des choses, mais il existe et peut rapidement devenir apparent dans des boucles serrées. en.wikipedia.org/wiki/Function_prologue
Dan Bechard
@Dan Eh bien, ça me dépasse LOL. Je pense qu'avec mes cas d'utilisation et comment la technologie s'améliore au fil du temps, je n'aurai jamais besoin de m'en soucier.
Altiano Gerung
2
@AltianoGerung S'il y a quelque chose que l'expérience m'a appris, c'est qu'avec une échelle suffisante, même le plus petit des problèmes devient assez important pour avoir de l'importance. Comme toujours, faites le profil avant de faire des hypothèses. :)
Dan Bechard
3

Faites de la boucle externe une boucle while et "Exit While" dans l'instruction if.

Andrew Thomas
la source
Cela fait exactement la même chose gotoqu'avec plus d'instructions, plus de verbosité et plus d'indentation. À quoi ça sert?
Dan Bechard
3

J'ai essayé de taper "exit pour" plusieurs fois et j'ai remarqué que cela fonctionnait et que VB ne m'a pas crié dessus. C'est une option, je suppose, mais elle avait juste l'air mauvaise.

Je pense que la meilleure option est similaire à celle partagée par Tobias. Mettez simplement votre code dans une fonction et faites-le revenir lorsque vous voulez sortir de vos boucles. Ça a l'air plus propre aussi.

For Each item In itemlist
    For Each item1 In itemlist1
        If item1 = item Then
            Return item1
        End If
    Next
Next
César
la source
Non, plusieurs "Quitter pour" n'entraînent pas le comportement souhaité. Le premier sort de la première boucle, les autres ne sont jamais atteints, donc n'ont aucun effet. À part cette suggestion, vous semblez avoir simplement répété les réponses précédentes.
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
Hitesh Paliwal
la source
Ne l'utilisez pas. Son comportement est mauvais. Voir plutôt la solution «variable booléenne» de la réponse acceptée de six ans plus tôt. S'il s'agissait d'une nouvelle approche, j'expliquerais ce qui la fait se comporter de manière incorrecte, mais cela ne vaut pas la peine de le faire, car l'approche a déjà été correctement illustrée dans cette réponse précédente.
ToolmakerSteve
0

Si je veux quitter une boucle for-to, je viens de définir l'index au-delà de la limite:

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

Poppa.

Poppa Mintin
la source
Je recommande de montrer comment cela s'applique à cette question. Prenez le code de la question et modifiez-le pour utiliser cette approche.
ToolmakerSteve