Romper / salir anidado en vb.net

122

¿Cómo me salgo de anidado o bucle en vb.net?

Intenté usar exit para pero saltó o rompió solo uno para el bucle solo.

¿Cómo puedo hacerlo para lo siguiente:

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
fuente
Lo que VB realmente necesita es una Exit For itemvariante de la declaración, similar a Next item. En los "buenos viejos tiempos" se podía explícitamente Nextel bucle externo. Hoy, VB da un error. Por supuesto, es más "constructivo" en su Exit Forlugar.
ysap

Respuestas:

199

Desafortunadamente, no hay una exit two levels of fordeclaración, pero hay algunas soluciones alternativas para hacer lo que desea:

  • Goto . En general, el uso gotose considera una mala práctica (y con razón), pero el uso gotoexclusivo para un salto hacia adelante de las declaraciones de control estructurado generalmente se considera correcto, especialmente si la alternativa es tener un código más complicado.

    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:
  • Bloque exterior ficticio

    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
  • Función separada : coloque los bucles dentro de una función separada, con la que se puede salir return. Sin embargo, esto puede requerir que pase muchos parámetros, dependiendo de cuántas variables locales use dentro del bucle. Una alternativa sería colocar el bloque en una lambda de varias líneas, ya que esto creará un cierre sobre las variables locales.

  • Variable booleana : esto podría hacer que su código sea un poco menos legible, dependiendo de cuántas capas de bucles anidados tenga:

    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
fuente
3
No puedo decir que ninguno de ellos sea mejor que el gotootro que la función si realmente tiene sentido.
Chris Marisic
2
Voy a usar eso gotoen un gran proyecto solo para recordar mis días de programación en qbasic, ah, en tiempos tan inocentes. de lo contrario, iría a hacer un maniquí.
Sharky
1
Prefiero el enfoque Try/ Exit Try, pero no soy fanático de la gotoopción.
JohnH
Tenga en cuenta que el método de "variable booleana" requiere múltiples variables y pruebas a medida que el nivel de anidamiento se profundiza. Esto se vuelve fugoso ...
ysap
1
@ysap: en mi experiencia, es raro que necesite múltiples variables booleanas. Normalmente, hay una condición de salida única (por ejemplo, "hecho") que una vez que se encuentra, todos los niveles de bucle deben salir. Sin embargo, prefiero hacer un método separado y usar "Retorno", esto encapsula limpiamente la construcción anidada.
ToolmakerSteve
16

Pon los bucles en una subrutina y llama return

Tobias Schittkowski
fuente
1
Vale la pena señalar que hay una sobrecarga asociada con dicha llamada que no está presente en la gotosolución más simple . Por supuesto, si el código es reutilizable, debería estar en una función ya de todos modos.
Dan Bechard
¿Cómo puede ser una sobrecarga? @Dan
Altiano Gerung
@AltianoGerung Bueno, mi comentario anterior asume que el compilador no optimiza e integra la llamada a la función. Todas las llamadas a funciones (suponiendo que no estén alineadas por el compilador) tienen la sobrecarga del prólogo y epílogo para actualizar el puntero de la pila base (así como hacer otras cosas como destructores de llamadas y recolección de basura si el idioma lo admite). Esto a menudo es minucioso en el gran esquema de las cosas, pero existe y puede hacerse evidente rápidamente en los circuitos cerrados. en.wikipedia.org/wiki/Function_prologue
Dan Bechard
@ Dan Bueno, eso está más allá de mí LOL. Creo que con mis casos de uso y cómo la tecnología mejora con el tiempo, nunca tendré que preocuparme por eso.
Altiano Gerung
2
@AltianoGerung Si hay algo que la experiencia me ha enseñado, es que con suficiente escala, incluso los problemas más pequeños se vuelven lo suficientemente grandes como para importar. Como siempre, perfile antes de hacer suposiciones. :)
Dan Bechard
3

Convierta el bucle externo en un bucle while y "Exit While" en la instrucción if.

Andrew Thomas
fuente
Esto hace exactamente lo mismo que gotocon más instrucciones, más verbosidad y más sangría. ¿Cuál es el punto de?
Dan Bechard
3

Experimenté escribiendo "salir por" varias veces y noté que funcionaba y VB no me gritó. Es una opción, supongo, pero se veía mal.

Creo que la mejor opción es similar a la que comparte Tobias. Simplemente ponga su código en una función y haga que regrese cuando quiera salir de sus bucles. Se ve más limpio también.

For Each item In itemlist
    For Each item1 In itemlist1
        If item1 = item Then
            Return item1
        End If
    Next
Next
Cesar
fuente
No, múltiples "Salir para" no dan como resultado el comportamiento deseado. El primero sale del primer bucle, nunca se alcanzan los adicionales, por lo que no tienen ningún efecto. Aparte de esa sugerencia, parece que simplemente has repetido respuestas anteriores.
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
fuente
No uses esto. Su comportamiento es incorrecto. En cambio, vea la solución de "variable booleana" de la respuesta aceptada de seis años antes. Si fuera un enfoque nuevo, explicaría qué hace que se comporte de manera incorrecta, pero no vale la pena hacerlo, ya que el enfoque ya se mostró correctamente en esa respuesta anterior.
ToolmakerSteve
0

Si quiero salir de un bucle for-to, simplemente configuro el índice más allá del límite:

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

Poppa

Poppa Mintin
fuente
Recomiendo mostrar cómo se aplica esto a esta pregunta. Tome el código de la pregunta y edítelo para usar este enfoque.
ToolmakerSteve