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

ハインジがこの質問に答えたように:

残念ながら、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。ただし、ループ内で使用するローカル変数の数によっては、多くのパラメーターを渡す必要がある場合があります。別の方法は、ブロックを複数行のラムダに配置することです。これにより、ローカル変数がクロージャになります。

  • ブール変数:ネストされたループのレイヤー数によっては、コードが少し読みにくくなる可能性があります。

    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に設定してから、中断することができます。次に、ブール値が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

ブール値を追加し、人が見つかったときにtrueに設定して、内側のループから抜け出します。次に、見つかったものが真であるかどうかを確認します。もしそうなら、外側のループから抜け出します。

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

888の答えに加えて:追加の関数は必ずしもパラメータを渡す必要はありません:

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)

キーワード:閉鎖

于 2012-12-28T16:47:09.760 に答える