In den letzten Tagen bin ich zum ersten Mal über eine Stelle gestolpert, an der ein „goto“ tatsächlich auch in C# einmal sinnvoll ist. Normalerweise versucht man den Sprung zu irgendwelchen Labeln zu verhindern und in den meisten Fällen braucht man den Befehl auch gar nicht. Allerdings stand ich gerade vor dem Problem, dass ich einen Switch-Case Block so definieren wollte, in dem nach einem Case die darunterliegenden Cases auch ausgeführt werden – also das break nicht notwendig ist. In Java ist das möglich, nicht aber in C#.
Hier ein Beispiel, wie ein solcher Switch-Case Block in Java aussehen könnte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
switch (variable.Length) { case 3: variable[2] += 1; //weiter mit nächstem Element case 2: variable[1] += 5; //weiter mit nächstem Element case 1: variable[0] += 9; break; default: throw new IllegalStateException("Something wrong..."); } |
Das Beispiel ist ganz einfach: Je nach Länge des Arrays wird auf die vorhandenen Elemente irgendeine Operation durchgeführt. In diesem sehr einfachen Beispiel ist das nur eine simple Addition. Lässt man in C# allerdings das break weg, quittiert der Compiler das mit einer Fehlermeldung („Control cannot fall through from one case label (‚case x:‘) to another“). Bleibt also nur Codeduplizierung, oder? Nein, nicht wirklich, denn genau hier kommt das vielgeschmähte goto ins Spiel, da man mit ihm die Labels (inkl. default) innerhalb des Switch-Case Blocks anspringen kann. Damit lässt sich das Beispiel von oben, das in Java funktioniert, ganz einfach auf C# umstellen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
switch (variable.Length) { case 3: variable[2] += 1; //weiter mit nächstem Element goto case 2; case 2: variable[1] += 5; //weiter mit nächstem Element goto case 1; case 1: variable[0] += 9; break; default: throw new InvalidOperationException("Something wrong..."); } |
Eine recht einfache Lösung, oder? Bisher kannte ich diese Vorgehensweise noch nicht, aber man lernt ja nie aus :).