Breaking / exit ซ้อนใน 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ฟังก์ชั่นอื่น ๆ ถ้ามันสมเหตุสมผลจริง
Chris Marisic

2
ฉันจะใช้มันgotoในโปรเจ็กต์ใหญ่เพื่อจำวันที่ฉันเขียนโปรแกรมใน qbasic อาเวลาที่ไร้เดียงสาเช่นนี้ ไม่งั้นฉันจะไปทำหุ่นจำลอง
Sharky

1
ฉันชอบTry/ Exit Tryวิธีการ แต่ฉันไม่ชอบgotoตัวเลือกนี้
JohnH

โปรดทราบว่าเมธอด "ตัวแปรบูลีน" ต้องการตัวแปรหลายตัวและการทดสอบเนื่องจากระดับการซ้อนจะลึกขึ้น สิ่งนี้กลายเป็นเรื่องน่า
กลัว

1
@ysap - จากประสบการณ์ของฉันมันหายากที่จะต้องมีตัวแปรบูลีนหลายตัว โดยปกติแล้วจะมีเงื่อนไขการออกเพียงครั้งเดียว (เช่น "เสร็จสิ้น") ที่เมื่อพบแล้วควรออกจากระดับลูปทั้งหมด อย่างไรก็ตามฉันชอบสร้างวิธีแยกต่างหากและใช้ "Return" ซึ่งจะห่อหุ้มโครงสร้างที่ซ้อนกันอย่างหมดจด
ToolmakerSteve

16

ใส่ลูปในรูทีนย่อยแล้วโทร return


1
เป็นที่น่าสังเกตว่ามีค่าใช้จ่ายที่เกี่ยวข้องกับการโทรที่ไม่มีอยู่ในgotoโซลูชันที่ง่ายกว่า แน่นอนว่าหากโค้ดสามารถใช้ซ้ำได้ก็ควรอยู่ในฟังก์ชันอยู่แล้ว
Dan Bechard

เป็นค่าโสหุ้ยได้อย่างไร? @ Dan
Altiano Gerung

@AltianoGerung ความคิดเห็นของฉันข้างต้นถือว่าคอมไพเลอร์ไม่ได้ปรับให้เหมาะสมและอินไลน์การเรียกฟังก์ชัน การเรียกใช้ฟังก์ชันทั้งหมด (สมมติว่าคอมไพเลอร์ไม่ได้อินไลน์) จะมีค่าใช้จ่ายของอารัมภบทและบทส่งท้ายในการอัปเดตตัวชี้สแต็กฐาน (รวมทั้งทำสิ่งอื่น ๆ เช่นตัวทำลายการโทรและรวบรวมขยะหากภาษานั้นรองรับ) สิ่งนี้มักจะเป็นข้อเล็ก ๆ น้อย ๆ ในรูปแบบที่ยิ่งใหญ่ของสิ่งต่าง ๆ แต่มีอยู่จริงและสามารถเห็นได้อย่างรวดเร็วในวงรอบที่แน่นหนา en.wikipedia.org/wiki/Function_prologue
Dan Bechard

@ แดนดีที่เกินฉันฮ่า ๆ ฉันคิดว่าด้วยกรณีการใช้งานของฉันและการปรับปรุงเทคโนโลยีเมื่อเวลาผ่านไปฉันจะไม่ต้องกังวลเกี่ยวกับเรื่องนี้
Altiano Gerung

2
@AltianoGerung หากมีประสบการณ์ใดที่สอนฉันได้ก็คือขนาดที่เพียงพอแม้แต่ปัญหาที่เล็กที่สุดก็ใหญ่พอที่จะมีความสำคัญ เช่นเคยโปรไฟล์ก่อนที่คุณจะตั้งสมมติฐานใด ๆ :)
Dan Bechard

3

ทำให้วงนอกเป็นลูป while และ "ออกขณะ" ในคำสั่ง if


สิ่งนี้จะเหมือนกับgotoคำแนะนำเพิ่มเติมการใช้คำฟุ่มเฟือยมากขึ้นและการเยื้องมากขึ้น ประเด็นคืออะไร?
Dan Bechard

3

ฉันได้ทดลองพิมพ์ "exit for" สองสามครั้งและสังเกตว่ามันใช้ได้ผลและ VB ไม่ได้ตะโกนใส่ฉัน เป็นตัวเลือกที่ฉันเดา แต่มันก็ดูแย่

ฉันคิดว่าตัวเลือกที่ดีที่สุดคล้ายกับที่ Tobias แบ่งปัน เพียงใส่รหัสของคุณในฟังก์ชันและส่งคืนเมื่อคุณต้องการแยกออกจากลูปของคุณ ดูสะอาดกว่าด้วย

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.