GoTo statements and alternatives in VB.NET

2019-06-16 06:03发布

I've posted a code snippet on another forum asking for help and people pointed out to me that using GoTo statements is very bad programming practice. I'm wondering: why is it bad?

What alternatives to GoTo are there to use in VB.NET that would be considered generally more of a better practice?

Consider this snippet below where the user has to input their date of birth. If the month/date/year are invalid or unrealistic, I'd like to loop back and ask the user again. (I'm using if statements to check the integer's size... if there's a better way to do this, I'd appreciate if you could tell me that also :D)

retryday:
    Console.WriteLine("Please enter the day you were born : ")
    day = Console.ReadLine
    If day > 31 Or day < 1 Then
        Console.WriteLine("Please enter a valid day")
        GoTo retryday
    End If

标签: vb.net goto
14条回答
地球回转人心会变
2楼-- · 2019-06-16 06:20

Questions about the merits of the GoTo statement (or rather the lack thereof) are perennial on this site. Click here for an example: Is GoTo still considered harmful?

With regards to an alternative to GoTo, in the provided snippet, a while loop would nicely do the trick, maybe something like:

day = -1
While (day < 0)
   Console.WriteLine("Please enter the day you were born : ")
   day = Console.ReadLine
   If day > 31 Or day < 1 Then
     Console.WriteLine("Please enter a valid day")
      day = -1
   End If
End While
查看更多
干净又极端
3楼-- · 2019-06-16 06:21

It is often recommended that we follow Dijkstra's advice in Go-To Statement Considered Harmful.

Donald Knuth answered Dijkstra pretty soundly. This example here is a modern version of one of his counterexamples. Personally I write infinite loops with internal breaks when I encounter this one but there's a few other rare cases where I will write GOTO statements.

The most common ones for me are breaking out of deeply nested loops and this pattern:

ContinueTry:
   Try
        'Worker code
   Catch ex as IO.IOException
        If MessageBox.Show(...) = DialogResult.Retry Then Goto ContinueTry
        Throw
   End Try

I also have two cases of large finite state machines with goto statements providing the transitions.

查看更多
甜甜的少女心
4楼-- · 2019-06-16 06:22

You can do almost anything that you can do with GOTOs with simple built-in language constructs like decision structures and loops, and GOTO statements often make for messy, impossible-to-understand spaghetti code. Loops and ifs and such have a clear, accepted, understandable usage.

See, as is usually suggested, Dijkstra's Go-To Statement Considered Harmful

查看更多
Emotional °昔
5楼-- · 2019-06-16 06:24

GOTOs are a pretty political issue. The 'solution' to GOTOs is to use other built-in navigation constructs like functions, methods, loops, etc. For VB, you could make a sub-procedure that runs that code, or put it in a While loop. You can google both of those subjects fairly easily.

查看更多
不美不萌又怎样
6楼-- · 2019-06-16 06:27

A little clunky but:

    Dim bContinue As Boolean

    Console.WriteLine("Enter a number between 1 and 31")

    Do
        Dim number As Integer = Console.ReadLine()
        If number >= 1 AndAlso number <= 31 Then
            bContinue = True
        Else
            Console.WriteLine("Please enter a VALID number between 1 and 31")
        End If
    Loop Until bContinue

Also consider some basic loops in "goto land"

        Dim i As Integer
startofloop1:

        Debug.WriteLine(i)
        i += 1
        If i <= 10 Then
            GoTo startofloop1
        End If

        i = 0

startofloop2:

        Debug.WriteLine(i * 2)
        i += 1
        If i <= 10 Then
            GoTo startofloop2
        End If

Here's the nice equivalent:

   For x As Integer = 0 To 10
        Debug.WriteLine(i)
    Next
    For x As Integer = 0 To 10
        Debug.WriteLine(i * 2)
    Next

Which is more readable and less error prone?

查看更多
何必那么认真
7楼-- · 2019-06-16 06:28
While True
    Console.WriteLine("Please enter the day you were born : ")
    day = Console.ReadLine
    If day > 31 Or day < 1 Then
        Console.WriteLine("Please enter a valid day")
        Continue
    Else
        Break
    End If
End While
查看更多
登录 后发表回答