2009-05-04 22 views
24

Piszę kod w VB.NET, który używa instrukcji switch, ale w jednym z przypadków musi przejść do innego bloku. W języku C# będzie wyglądać tak:VB.NET Switch Statement GoTo Case

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; 
} 

Jednak nie wiem, jak przekonwertować to do VB.NET. Próbowałem to:

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  

Ale gdy to zrobię, pojawia się błąd kompilatora: "Oczekiwano identyfikatora". W "Przypadku" jest zawrotna linia. Jakieś pomysły?

Czy używanie w tym przypadku instrukcji GoTo jest niewłaściwe? Wydaje się, że inaczej musiałbym to napisać ponownie.


I zmieniły mojego kodu do następująco:

If otherFactor AndAlso parameter = "mvrType" Then 
    'does something here 
Else 
    ' My original "Select Case statement" here without the case for "mvrType" 
End If 

Odpowiedz

13

nie ma odpowiednika w VB.NET, że udało mi się znaleźć. W przypadku tego fragmentu prawdopodobnie będziesz chciał go otworzyć w Reflectorze i zmienić typ wyjścia na VB, aby uzyskać dokładną kopię potrzebnego kodu. Na przykład, gdy umieściłem następujące w Reflectorze:

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; 
} 

dał mi następujące wyjście VB.NET.

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") 

Jak widać, można wykonać tę samą instrukcję case switch za pomocą instrukcji If. Zwykle nie polecam tego, ponieważ utrudnia to zrozumienie, ale VB.NET nie obsługuje tych samych funkcji, a użycie Reflectora może być najlepszym sposobem uzyskania kodu potrzebnego do pracy bez dużo bólu.

Aktualizacja:

tylko potwierdził, że nie może zrobić dokładnie to samo w VB.NET, ale nie obsługuje kilka innych przydatnych rzeczy. Wygląda na to, że konwersja instrukcji IF jest najlepsza, a może refaktoryzacja. Oto definicja dla Select ... Case

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

+0

Bardzo interesujące. Jaka jest korzyść z używania Select statement? Myślałem, że zastosowano tabelę odnośników? Tak czy siak - to jest to, co podejrzewałem (że VB.NET go nie obsługiwał). – KTF

+0

Żadna instrukcja select lub instrukcja switch nie jest po prostu "magią" kompilatora w .NET, w rzeczywistości przekształca wszystko w coś trudniejszego do odczytania, jeśli ... Instrukcja else. –

+4

Nie zawsze prawda (wiem, że ten komentarz jest dość stary, ale dla mnie nowy!) - http://blogs.msdn.com/abhinaba/archive/2006/12/13/why-can-we-only-use -constants-in-a-switch-case-statement.aspx – Ant

4

nie jestem pewien, że to dobry pomysł, aby użyć goto ale jeśli chcesz go używać, można zrobić coś takiego to:

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 

Jak powiedziałem, chociaż działa GoTo nie jest dobra praktyka, więc oto kilka alternatywnych rozwiązań:

Korzystanie 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 

Korzystanie wartość logiczną ...

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 

Zamiast ustawiać zmienną logiczną można też wywołać metodę bezpośrednio w obu przypadkach ...

+0

Brakuje punktu w obudowie specyficznego dla przełącznika GoTo, nie działa jak GoTo, tylko skok proceduralny do innej sprawy. –

+0

Tak, to, o czym mówi Nick Berardi, jest dokładnie tym, czego potrzebuję. Czy jest coś takiego w VB.NET? – KTF

+0

Oto jak GoTo działałoby pod VB.NET – jgallant

19

Dlaczego po prostu nie robimy tego tak:

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 

Nie jestem pewien, czy nie mając przypadku na końcu jest duży d eal lub nie, ale wydaje się, że tak naprawdę nie potrzebujesz iść, jeśli po prostu umieścić go w innym oświadczeniu, jeśli.

+0

Ponadto, poniższy artykuł wyjaśnia krytykę instrukcji goto. http://pl.wikipedia.org/wiki/GOTO#Criticism_of_goto_usage – ryanulit

+0

To znaczy, że musiałbym dwukrotnie napisać kod przetwarzania; po pierwsze dla przypadku "Else" w instrukcji If, a po drugie dla instrukcji "Case Else" w instrukcji "Select". Musiałbym zaktualizować oba, a właściwie kilka linii kodu. To wygląda na zły pomysł. – KTF

+0

To zły pomysł na duplikowanie kodu, zły pomysł na używanie goto i zły pomysł na posiadanie tak dużej ilości kodu (jak sugerują twoje komentarze) w strukturze SWITCH. Wyodrębnij metodę (zduplikowany kod) do funkcji; rozważ także zastąpienie polimorfizmu dziedziczeniem. –

2

należy zadeklarować etykietę pierwszy użyj:

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 
+0

Ten sam problem co Meta-Knight, nie chcesz używać rzeczywistych instrukcji GoTo. GoTo w instrukcji CASE to skok proceduralny do innej sprawy, a nie skok liniowy, jak to zrobiono powyżej. –

+2

Wow, dlaczego w dół? działa, po prostu spróbuj :) – Sadegh

+0

@Nick po prostu spróbuj, koleś – Sadegh

11

Dlaczego po prostu nie byłaby domyślny przypadek jako metodę i wywołać ją z obu tych miejscach? Powinno to być bardziej czytelne i pozwolić na późniejszą zmianę kodu w bardziej efektywny sposób.

1
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 
3

W VB.NET można zastosować wiele warunków, nawet jeśli inne warunki nie mają zastosowania do parametru Wybierz. Patrz poniżej:

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

-1 'Domyślna wielkość goto' (lub 'goto case else') jest dla mnie błędem składni. –

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

Czy istnieje powód dla goto? Jeśli nie spełnia kryterium if, po prostu nie wykona funkcji i przejdzie do następnego przypadku.