1

可能重复:
打破/退出嵌套在 vb.net

GOTO从双 ForEach 退出的唯一方法吗?

For Each city in cities
  For Each person in city.People
    If IsOK(person) GOTO Found_
  Next person
Next city

Found_: 
' ...

问题是针对 VB.NET,但也想知道 C#...

4

8 回答 8

9

把它放在单独的函数中

  Private Function FindPerson(cities As List(of City)) As Person
     For Each city in cities
        For Each person in city.People
           If IsOK(person) Return person
        Next person
     Next city
     Return Nothing
  End Function

和...

  Private Function ContainsPerson(cities As List(of City)) As Bool  
     For Each city in cities
        For Each person in city.People
           If IsOK(person) Return True
        Next person
     Next city
     Return False
  End Function

编辑:固定 VB 语法

于 2012-12-28T14:48:31.737 回答
5

为什么不只使用 LINQ?

C#:

// Or use SingleOrDefault(...) if there can ever only be one.
var person = Cities.SelectMany(city => city.People)
                   .FirstOrDefault(person => IsOK(person));

if (person != null)
{
    ...
}

VB.Net(我最好的尝试,我没有那么详细):

// Or use SingleOrDefault(...) if there can ever only be one.
Dim person = Cities.SelectMany(Function(city) city.People)
                   .FirstOrDefault(Function(person) IsOK(person));

If person Not Nothing Then
    ...
End If

如果您要做的只是查看是否有任何IsOK(person),请改用Any(...)扩展方法:

C#:

var isOK = Cities.SelectMany(city => city.People)
                 .Any(person => IsOK(person));

VB.Net(我最好的尝试,我没有那么详细):

Dim isOK = Cities.SelectMany(Function(city) city.People)
                 .Any(Function(person) IsOK(person));
于 2012-12-28T15:06:52.173 回答
4

正如 Heinzi 在这个问题中回答的那样:

不幸的是,没有exit two levels of for声明,但是有一些解决方法可以避免Goto,这被认为是不好的做法

  • 假外块

    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。不过,这可能需要您传递大量参数,具体取决于您在循环中使用了多少局部变量。另一种方法是将块放入多行 lambda,因为这将在局部变量上创建一个闭包。

  • 布尔变量:这可能会使您的代码的可读性降低,具体取决于您拥有多少层嵌套循环:

    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
    
于 2012-12-28T15:06:19.630 回答
2

您可以在第一个循环中放置一个 bool 并在内部循环中将其设置为 false 然后中断。如果布尔为假,则在外循环中中断。

于 2012-12-28T14:46:53.887 回答
0

你也可以抛出异常:

Try
  For Each city in cities
    For Each person in city.People
      If IsOK(person) Throw New FoundException
    Next person
  Next city
Catch ex As FoundException
  DoFoundStuff
End Try

警告:我的意思只是表明异常是退出多个嵌套循环的一个选项,而不是在此代码示例的特定情况下合适。特别是,异常通常应限于“异常/错误”条件而不是“正常”条件。例如,如果您只是将“If”更改为“If Not IsOK ....”,则例外可能是正确的解决方案。

于 2012-12-28T14:47:20.613 回答
0

添加一个布尔值并将其设置为真,当找到该人并从内部循环中断时。然后检查发现是否为真。如果是这样,则从外部循环中中断。

bool found;
For Each city in cities
    For Each person in city.People
        If IsOK(person) 
            found = true
            Exit For
        End If
    Next person
    If (found) 
        Exit For
    End If
 Next city
于 2012-12-28T14:50:18.463 回答
0

写 vb.net 已经很长时间了,但以下应该可以工作(我认为)

    Dim found As Boolean
    For Each city In cities
        If found = True Then
            Exit For
        End If
        For Each person In city.People

            If IsOK(person) Then
                found = True
                Exit For
            End If
        Next person
    Next city
于 2012-12-28T14:56:34.433 回答
0

In addition to 888's answer: An extra function does not necessarily need params to be passed:

Dim a, b, c As Integer
    a = 100
    b = 50
    c = 20

    Dim r = Function()
                For i = 1 To a
                    For j = 1 To b
                        For k = 1 To c
                            If i * j * k = 150 Then Return 1
                        Next
                    Next
                Next
                Return 2
            End Function

    Console.WriteLine(r)

Keyword: closure

于 2012-12-28T16:47:09.760 回答