Jedyny przypadek gdy GOTO nie jest FUJ
Jedna z zasad, której młodzi programiści uczą się na początku swojej kariery (żeby nie powiedzieć "wysysają z mlekiem swojego nauczyciela") brzmi:
"instrukcja GOTO w językach programowania poziomu wyższego niż asembler istnieje po to i tylko po to, aby świadomie ignorować jej egzystencję"
Prawda? I co tu dużo gadać, ciężko się z tą teorią nie zgodzić. Jedyne do czego prowadzi używanie tej instrukcji to powstanie tzw "unmaintable spaghetti code".
Chyba że...
Jest moim zdaniem jeden scenariusz, w którym instrukcja GOTO czasami się w C# przydaje. Chodzi mianowicie o "switch fallthrough" - spójrzmy na następujący kod:
1: switch (number)
2: {
3: case 0:
4: DoSomething();
5: case 1:
6: DoSomethingElse();
7: break;
8: default:
9: throw new Exception();
10: }
W Javie, w C, w C++ i w milionie innych języków taka kontrukcja spowoduje wykonanie obu metod dla number==0 oraz jednej metody dla number==1. A co się stanie w C#? W C# dostaniemy w twarz błędem kompilacji: "Control cannot fall through from one case label ('case 0:') to another" (wtrącenie: coś mi się kojarzy, że w C# 1.0 taka konstrukcja była poprawna, jednak nie mam zainstalowanego VS 2003 żeby to sprawdzić i nie dam sobie niczego uciąć). Dobrze to czy źle... nie mnie teraz oceniać. Zainteresowanych odsyłam do uzasadnienia w dziale Visual C# Developer Center. Idźmy jednak dalej: aby osiągnąć takie samo zachowanie w C# musimy jawnie je opisać w ten sposób:
1: switch (number)
2: {
3: case 0:
4: DoSomething();
5: goto case 1;
6: case 1:
7: DoSomethingElse();
8: break;
9: default:
10: throw new Exception();
11: }
Inaczej po prostu się nie da, i jest to moim zdaniem jedyny (a 1>0!) uzasadniony scenariusz użycia konstrukcji GOTO w C#.
Na koniec jeszcze kilka słów, coby nie powstało niezamierzone "misandersztendiś": pomiędzy liniami tego posta nie ma stwierdzenia "switch z goto jest dobry". Instrukcja switch sama w sobie trochę zalatuje makaronem (na szczęście da się z tym coś zrobić). Jeśli jednak i tak mamy w kodzie switcha to równie dobrze możemy weń wstawić goto, lepsze to niż wielokrotne pisanie tych samych instrukcji dla różnych case'ów (ileż amerykanizmów i anglizmów w jednym zdaniu! aż poczułem hamburgera w ustach i krople deszczu na czole...).
UWAGA! Stosować z rozwagą! Głupota i bezmyślność może dość szybko skończyć się wiecznym gniciem w programistycznej "hall of shame", czyli The Daily WTF. I żeby potem nie było na mnie;).