Thursday, May 5, 2011

VB.NET Switch Statement GoTo Case

I am writing some code in VB.NET that uses a switch statement but in one of the cases it needs to jump to another block. In C# it would look like this:

    switch (parameter)
    {
        case "userID":
            // does something here.
        case "packageID":
            // does something here.
        case "mvrType":
            if (otherFactor)
            {
                // does something here.
            }
            else
            {
                goto default;
            }
        default:
            // does some processing...
        break;
    }

However, I don't know how to convert this to VB.NET. I tried this:

Select Case parameter 
    Case "userID"
  ' does something here.
 Case "packageID"
  ' does something here.
 Case "mvrType" 
  If otherFactor Then 
   ' does something here. 
  Else 
   GoTo Case Else 
  End If 
 Case Else 
  ' does some processing... 
  Exit Select 
End Select

But when I do this I get a compiler error: "Identifier expected". There'sa squiggly line under "Case". Any ideas?

Also, is it wrong to use a GoTo statement in this case? It seems any other way I would have to re-write it.


I have changed my code to as follows:

If otherFactor AndAlso parameter = "mvrType" Then 
    'does something here 
Else 
    ' My original "Select Case statement" here without the case for "mvrType" 
End If
From stackoverflow
  • I'm not sure it's a good idea to use a GoTo but if you do want to use it, you can do something like this:

    Select Case parameter 
        Case "userID"
                    ' does something here.
            Case "packageID"
                    ' does something here.
            Case "mvrType" 
                    If otherFactor Then 
                            ' does something here. 
                    Else 
                            GoTo caseElse
                    End If 
            Case Else
    caseElse:
                    ' does some processing... 
    End Select
    

    As I said, although it works, GoTo is not good practice, so here are some alternative solutions:

    Using elseif...

    If parameter = "userID" Then
        ' does something here.
    ElseIf parameter = "packageID" Then
        ' does something here.
    ElseIf parameter = "mvrType" AndAlso otherFactor Then
        ' does something here.
    Else
        'does some processing...
    End If
    

    Using a boolean value...

    Dim doSomething As Boolean
    
    Select Case parameter
    Case "userID"
         ' does something here.
    Case "packageID"
         ' does something here.
    Case "mvrType"
         If otherFactor Then
              ' does something here. 
         Else
              doSomething = True
         End If
    Case Else
         doSomething = True
    End Select
    
    If doSomething Then
         ' does some processing... 
    End If
    

    Instead of setting a boolean variable you could also call a method directly in both cases...

    Nick Berardi : You are missing the point of the switch case specific GoTo, it doesn't act like a GoTo, just a procedural jump to another case.
    KTF : Yeah- What Nick Berardi is talking about is exactly what I need. Is there anything like that in VB.NET?
    Jon : This is how the GoTo would work under VB.NET
    Meta-Knight : I don't think there's such a thing as a switch case specific GoTo in Vb.Net. But I would probably use If/Elseif, or set some boolean variable to true and do the processing outside of the select case.
  • Why not just do it like this:

    Select Case parameter     
       Case "userID"                
          ' does something here.        
       Case "packageID"                
          ' does something here.        
       Case "mvrType"                 
          If otherFactor Then                         
             ' does something here.                 
          Else                         
             ' do processing originally part of GoTo here
             Exit Select  
          End If      
    End Select
    

    I'm not sure if not having a case else at the end is a big deal or not, but it seems like you don't really need the go to if you just put it in the else statement of your if.

    ryanulit : Also, the article below explains criticisms of the goto statement. http://en.wikipedia.org/wiki/GOTO#Criticism_of_goto_usage
    KTF : This would means I would have to write the processing code twice; first for the "Else" case on the If statement, and second for the "Case Else" statement on the "Select" statement. I would have to update both, and its actually quite a few lines of code. It seems like a real bad idea.
    Carl Manaster : It's a bad idea to have so much code duplicated, a bad idea to use goto, and a bad idea to have so much code (as implied by your comments) in a SWITCH structure. Extract the method (the duplicated code) into a function; also consider replacing polymorphism by inheritance.
  • you should declare label first use this :

        Select Case parameter 
            Case "userID"
                        ' does something here.
                Case "packageID"
                        ' does something here.
                Case "mvrType" 
                        If otherFactor Then 
                                ' does something here. 
                        Else 
                                GoTo else
                        End If 
    
                Case Else 
    else :
                        ' does some processing... 
                        Exit Select 
        End Select
    
    Nick Berardi : Same issue as Meta-Knight, you don't want to use actual GoTo statements. A GoTo in the a CASE statement is a procedural jump to another case, not a line jump as you have done above.
    Adinochestva : wow , why downvote ? it works , just try it :)
    Adinochestva : @Nick just try it dude
    Nick Berardi : wasn't down voted because it didn't work, it was down voted because it is a bad solution and not the same thing as the original C# that the OP is trying to convert.
  • There is no equivalent in VB.NET that I could find. For this piece of code you are probably going to want to open it in Reflector and change the output type to VB to get the exact copy of the code that you need. For instance when I put the following in to Reflector:

    switch (args[0])
    {
        case "UserID":
         Console.Write("UserID");
         break;
        case "PackageID":
         Console.Write("PackageID");
         break;
        case "MVRType":
         if (args[1] == "None")
          Console.Write("None");
         else
          goto default;
         break;
        default:
         Console.Write("Default");
         break;
    }
    

    it gave me the following VB.NET output.

    Dim CS$4$0000 As String = args(0)
    If (Not CS$4$0000 Is Nothing) Then
        If (CS$4$0000 = "UserID") Then
            Console.Write("UserID")
            Return
        End If
        If (CS$4$0000 = "PackageID") Then
            Console.Write("PackageID")
            Return
        End If
        If ((CS$4$0000 = "MVRType") AndAlso (args(1) = "None")) Then
            Console.Write("None")
            Return
        End If
    End If
    Console.Write("Default")
    

    As you can see you can accomplish the same switch case statement with If statements. Usually I don't recommend this because it makes it harder to understand, but VB.NET doesn't seem to support the same functionality, and using Reflector might be the best way to get the code you need to get it working with out a lot of pain.

    Update:

    Just confirmed you cannot do the exact same thing in VB.NET, but it does support some other useful things. Looks like the IF statement conversion is your best bet, or maybe some refactoring. Here is the definition for Select...Case

    http://msdn.microsoft.com/en-us/library/cy37t14y.aspx

    KTF : Very interesting. What is the benefit of using Select statements? I thought a lookup table was used? Either way- this is what I suspected (that VB.NET did not support it)
    Nick Berardi : No a select statement or a switch statement is just compiler "magic" in .NET, it actually transforms everything in to a big harder to read if-else statement.
    Ant : Not always true (I know this comment is quite old, but it's new to me!) - http://blogs.msdn.com/abhinaba/archive/2006/12/13/why-can-we-only-use-constants-in-a-switch-case-statement.aspx
  • Why don't you just refactor the default case as a method and call it from both places? This should be more readable and will allow you to change the code later in a more efficient manner.

  • Select Case parameter ' does something here. ' does something here. Case "userID", "packageID", "mvrType" If otherFactor Then ' does something here. Else goto case default End If Case Else ' does some processing... Exit Select End Select

0 comments:

Post a Comment