Unterschiede zwischen den Anweisungen Select Case und switch
Die bekanntesten Programmiersprachen zur Entwicklung für das .NET Framework bieten eigene Anweisungen zur Verzweigung an, die über die von If gebotenen Möglichkeiten hinausgehen. In Visual Basic .NET steht zur Verzweigung die Anweisung Select Case, in C# switch zur Verfügung. Auf den ersten Blick scheinen beide Anweisungen hinsichtlich ihrer Funktionalität ungefähr ebenbürtig, bei genauerer Betrachtung können jedoch einige wichtige Unterschiede in Funktionsumfang und Verhalten der Anweisungen festgestellt werden, deren Beschreibung sich dieser Artikel widmet. Diese Unterschiede sind, insbesondere bei der Anweisung switch in C#, historisch bedingt. Syntax und Semantik von Select Case in Visual Basic .NET wurden weitgehend aus Visual Basic 6.0 übernommen. switch in C# hingegen ist der gleichnamigen Anweisung aus C nachempfunden.
-
Bei
Select Casekönnen mehrere Bedingungen in einemCase-Zweig zusammengefaßt werden (Case 1, 7, 12, 43), beiswitchist dies nicht möglich. Durch das Zusammenfassen mehrerer Zweige in einem wird die Lesbarkeit des Codes erhöht, indem die Übersicht gefördert wird und Codesegmente nicht dupliziert werden müssen. In C war ein ähnliches Verhalten erzielbar, indem mehrerecase-Zweige ohnebreak-Anweisung spezifiziert wurden. Diese Möglichkeit des „Durchfallens“ besteht in C# jedoch ebenfalls nicht, dabreakzwingend angegeben werden muß. Stattdessen können entweder mehrerecase-Zweige direkt hintereinander notiert oder die Ausführung kann explizit mittelsgoto casean weitere Zweige übertragen werden;breakkann in hierbei entfallen.switch (a) { case 1: case 2: case 3: ⋮ break; case 4: ⋮ break; } -
Der Datentyp, anhand von dessen Werten verzweigt wird, muß die Definition konstanter Werte zulassen. Daher ist keine Verzweigung anhand von Instanzen eines beliebigen Datentyps möglich.
switchkann daher nur für numerische Datentypen, Aufzählungstypen und den Datentypstringgenutzt werden. Das Verzweigen anhand von nicht-konstanten Objekten, wie sie etwa in Aufzählungen wieColor,PensundBrushesvorkommen, wird damit nicht unterstützt. Anstatt vonswitchmuß in diesen Fällen aufif-Anweisungen mit mehrerenelse if-Zweigen zurückgegriffen werden. Außerdem können beiSelect Casenahezu beliebige Auswahlbedingungen angegeben werden:Select Case True Case Button Is Me.Button1 ⋮ Case Button Is Me.Button2, Button Is Me.Button3 ⋮ End Select Select Case 2 Case Test1(1, 2, 3), a + 2 ⋮ Case … ⋮ End Select Select Case Test2(…) Case Is < 10 + a, 21 To 30, 45, 46 ⋮ Case 15 To 20 ⋮ End Select Select Case Me.BackColor Case Color.Red, Color.Green ⋮ Case Color.Blue ⋮ End Select -
Ein weiterer Unterschied besteht in den Gültigkeitsbereichen, die durch die Zweige der Auswahlanweisungen
Select Caseundswitchaufgespannt werden.Case-Zweige definieren einen eigenen Gültigkeitsbereich. Deshalb ist es möglich, Variablen gleichen Namens in mehreren Zweigen zu deklarieren, wie dies auch bei derIf-Anweisung inElse If-Blöcken möglich ist. Dagegen stellt der Bereich zwischencaseundbreakbeiswitchnicht automatisch einen Gültigkeitsbereich dar. Ein solcher müßte bei Bedarf explizit über geschweifte Klammern definiert werden. Das weitaus sauberere Entfernen der Anweisungbreakbei gleichzeitiger impliziter Beendigung der Überprüfung der Bedingungen voncase-Zweigen wurde mit der Begründung nicht vorgenommen, daß C++-Entwickler dadurch verunsichert würden, wenn sichswitchin C++ und C# voneinander unterscheiden würden:switch (a) { case 1: { int i = …; ⋮ } break; case 2: { int i = …; ⋮ } break; } switch (a) { case 1: int b = 2; break; case 2: b = a + 3; break; }Der zweiten
switch-Anweisung im vorigen Listing gilt dabei besondere Aufmerksamkeit. Die im erstencase-Zweig deklarierte lokale Variablebsteht auch in den nachfolgendencase-Zweigen zur Verfügung; die Deklaration einer Variablen mit gleichem Namen ist daher nicht möglich, ohne einen weiteren Block einzuführen. Dies ist unintuitiv, da die Deklaration, so man sie als Anweisung interpretiert, nicht ausgeführt werden sollte, wenn die Bedingung des erstencase-Zweigs nicht erfüllt ist. Letzteres muß zwingend der Fall sein, wenn der Code im zweitencase-Zweig zur Ausführung gelangt. Ersetzt man diebreak-Anweisung im erstencase-Zweig durch die Anweisunggoto case 2sowieb = a + 3durcha = b + 3, wird weiterhin der Compilerfehler Use of unassigned variable 'b' ausgelöst! Folgendes Listing zeigt kompilierbaren Code in Visual Basic .NET, bei dem Variablen gleichen Namens in mehrerenCase-Zweigen deklariert werden:Select Case a Case 1 Dim b As Integer ⋮ Case 2 Dim b As Integer ⋮ End Select -
Anders als bei
Select Casestellen die konstanten Ausdrücke, anhand derer verzweigt wird, in C# gleichzeitig Sprungziele dar, auf die von anderencase-Zweigen heraus mitgoto case constant-expressiongesprungen werden kann. Eine exakte Duplizierung eines bestehenden konstanten Ausdrucks, der in einemcase-Zweig benutzt wird, ist dabei nicht erforderlich; lediglich der Wert des Ausdrucks muß gleich sein. In Visual Basic .NET läßt sich ein ähnliches Verhalten durch Verwendung benannter oder unbenannter Sprungmarken vor den jeweiligenCase-Zweigen erzielen, die mittels der AnweisungGoToangesprungen werden können. Wenngleich letztere Variante nicht so fest in die Syntax der Programmiersprache integriert ist, wie dies beiswitchder Fall zu sein scheint, bietet sie zumindest die Möglichkeit der ausdrucksstarken Benennung der Sprungmarken.switch (a) { case 2: ⋮ break; case 6: ⋮ goto case 7; break; case 7: ⋮ if (…) goto case 1 + 2 + 3; break; }