Zastanawiałem się, czy ktoś nadal używa składni słowa kluczowego „goto” w C # i jakie są tego możliwe powody.
Zwykle postrzegam wszelkie stwierdzenia, które powodują, że czytelnik przeskakuje po kodzie, jako złą praktykę, ale zastanawiałem się, czy istnieją jakieś wiarygodne scenariusze użycia takiej składni?
c#
.net
coding-style
goto
Brian Scott
źródło
źródło
goto
do przerwania pętli i powrotu do instrukcji początkowej zgodnie z określonym warunkiemOdpowiedzi:
Istnieją (rzadkie) przypadki, w których goto może faktycznie poprawić czytelność. W rzeczywistości dokumentacja, do której utworzyłeś łącze, zawiera dwa przykłady:
Oto przykład tego ostatniego:
Oczywiście istnieją również inne sposoby obejścia tego problemu, takie jak refaktoryzacja kodu na funkcję, użycie dookoła niego pustego bloku itp. (Szczegóły w tym pytaniu ). Na marginesie, projektanci języka Java zdecydowali się całkowicie zakazać goto i zamiast tego wprowadzić oznaczoną przerwę .
źródło
Pamiętam tę część
Na coś takiego
Odnieś się do tego
źródło
Używam go szeroko w Eduasync, aby pokazać rodzaj kodu, który kompilator generuje dla Ciebie podczas używania metod asynchronicznych w C # 5. To samo można zobaczyć w blokach iteratorów.
Jednak w „normalnym” kodzie nie pamiętam, kiedy ostatnio go używałem ...
źródło
Goto świetnie nadaje się do przerywania wielu pętli, w których break nie działałby dobrze (powiedzmy, gdy wystąpił błąd), a jak powiedział Kragen, goto jest używany przez kompilator do generowania instrukcji przełączania i innych rzeczy.
źródło
Nie pamiętam, żebym kiedykolwiek używał
goto
. Ale może poprawia intencję wiecznej pętli, z której naprawdę nigdy nie chcesz wyjść (niebreak
, ale nadal możeszreturn
lubthrow
):Z drugiej strony
while (true)
wystarczy prosty ...Ponadto użytkownik mógłby użyć w sytuacji, gdy chcesz pierwszej iteracji pętli rozpocznie się w środku pętli: Spójrz tutaj dla przykładu.
źródło
goto
.. iwhile(true) {..}
nie jest interesującym stosowanie ..Kompilator używa
goto
instrukcji w różnych fragmentach generowanego kodu, na przykład w generowanych typach bloków iteratorów (generowanych przy użyciuyield return
słowa kluczowego - jestem prawie pewien, że wygenerowane typy serializacji XML również majągoto
gdzieś kilka instrukcji.Zobacz szczegóły implementacji bloku iteratora: automatycznie generowane maszyny stanu, aby uzyskać więcej informacji na temat tego, dlaczego / jak kompilator C # obsługuje to.
Poza wygenerowanym kodem nie ma dobrego powodu, aby używać
goto
instrukcji w normalnym kodzie - sprawia, że kod jest trudniejszy do zrozumienia, a w rezultacie bardziej podatny na błędy. Z drugiej strony, użyciegoto
instrukcji w wygenerowanym kodzie, takim jak ten, może uprościć proces generowania i zwykle jest w porządku, ponieważ nikt nie będzie czytać (ani modyfikować) wygenerowanego kodu i nie ma szans na popełnienie błędów, ponieważ maszyna pisze.Zobacz instrukcję Go-to uważaną za szkodliwą dla argumentu przeciwko,
goto
a także klasyczny fragment historii programowania.źródło
goto
nie. Coś do rozważenia.Procesor implementuje co najmniej jedną instrukcję skoku i jestem pewien, że wiele instrukcji używa ich w swojej implementacji lub interpretacji.
Jedną z dobrych rzeczy w używaniu języka trzeciej lub czwartej generacji jest to, że te fizyczne szczegóły są od nas oderwane. Chociaż powinniśmy pamiętać o prawie nieszczelnej abstrakcji , myślę, że powinniśmy również używać naszych narzędzi zgodnie z ich przeznaczeniem ( przepraszam ). Gdybym pisał kod i
goto
wydawał się dobrym pomysłem, to byłby czas na refaktoryzację. Celem ustrukturyzowanego języka jest uniknięcie tych „skoków” i stworzenie logicznego przepływu w naszej inżynierii.Powinienem unikać używania,
break
ale nie mogę przeoczyć korzyści związanych z wydajnością. Jeśli jednak mam zagnieżdżone pętle, które są wzajemnie potrzebne,break
nadszedł czas na refaktoryzację.Jeśli ktoś może zaproponować zastosowanie tego
goto
, wydaje się lepsze niż refaktoryzacja, chętnie wycofam swoją odpowiedź.Mam nadzieję, że nie jestem winny pośpiechu do „ szopy rowerowej ” tutaj. Jak mówi Kragen, to, co jest wystarczająco dobre dla Dijkstry, jest wystarczająco dobre dla mnie.
źródło
dynamic
obiekt i przechodząc po nim wykres obiektu, który zawiera wiele słowników, aby przejść do potrzebnych wartości. Nie ma sensu używać metod, które mają parametr,dynamic
ale oczekują dokładnego kształtu obiektu. Z goto, aby przełamać wiele warstw i kontynuować spacer po kolekcji tych obiektów. [Nie jestem właścicielem typów, więc nie mogę zapewnić lepszego dostępu, więc jest to refleksja lub dynamika]Goto nigdy nie jest lepsze. I kontynuuj, łam (z wyjątkiem przełącznika / przypadku), (wielokrotny) powrót i rzut również powinny być ograniczone do minimum. Nigdy nie chcesz uciec ze środka pętli gniazd. Zawsze chcesz, aby instrukcje sterujące pętli miały całą kontrolę pętli. Wcięcie zawiera informacje, a wszystkie te stwierdzenia odrzucają te informacje. Równie dobrze możesz usunąć wszystkie wcięcia.
źródło