Czy istnieje sposób na przejrzenie wielu instrukcji case bez podania nazwy case value:
powtarzania?
Wiem, że to działa:
switch (value)
{
case 1:
case 2:
case 3:
// Do some stuff
break;
case 4:
case 5:
case 6:
// Do some different stuff
break;
default:
// Default stuff
break;
}
ale chciałbym zrobić coś takiego:
switch (value)
{
case 1,2,3:
// Do something
break;
case 4,5,6:
// Do something
break;
default:
// Do the Default
break;
}
Czy mam na myśli tę składnię z innego języka, czy coś pomijam?
c#
switch-statement
theo
źródło
źródło
,
i taki, który nie jest współdzielony z żadnym innym językiem w stylu C. Wydałoby mi się to znacznie brudniejsze.Odpowiedzi:
Nie ma składni w C ++ ani C # dla drugiej metody, o której wspomniałeś.
W pierwszej metodzie nie ma nic złego. Jeśli jednak masz bardzo duże zakresy, po prostu użyj serii instrukcji if.
źródło
Wydaje mi się, że na to już odpowiedziano. Myślę jednak, że nadal możesz mieszać obie opcje w sposób składniowy, lepiej:
źródło
Ta składnia pochodzi z Visual Basic Select ... Case Case :
Nie można użyć tej składni w języku C #. Zamiast tego musisz użyć składni z pierwszego przykładu.
źródło
W C # 7 (domyślnie dostępne w Visual Studio 2017 / .NET Framework 4.6.2) przełączanie oparte na zakresie jest teraz możliwe dzięki instrukcji switch i pomogłoby w rozwiązaniu problemu PO.
Przykład:
Uwagi:
(
i)
nie są wymagane w tymwhen
stanie, ale zostały użyte w tym przykładzie do podkreślenia porównania.var
może być również używany zamiastint
. Na przykład:case var n when n >= 7:
.źródło
Możesz pominąć nowy wiersz, który daje:
ale uważam ten zły styl.
źródło
.NET Framework 3.5 ma zakresy:
Enumerable.Range from MSDN
możesz go używać z „zawiera” i instrukcją IF, ponieważ jak ktoś powiedział, że instrukcja SWITCH używa operatora „==”.
Oto przykład:
Ale myślę, że możemy się lepiej bawić: ponieważ nie będziesz potrzebować zwracanych wartości, a ta akcja nie przyjmuje parametrów, możesz łatwo używać akcji!
Stary przykład z tą nową metodą:
Ponieważ podajesz akcje, a nie wartości, powinieneś pominąć nawias, jest to bardzo ważne. Jeśli potrzebujesz funkcji z argumentami, po prostu zmień typ
Action
naAction<ParameterType>
. Jeśli potrzebujesz zwracanych wartości, użyjFunc<ParameterType, ReturnType>
.W C # 3.0 nie ma łatwej częściowej aplikacji do opisania faktu, że parametr case jest taki sam, ale tworzysz małą metodę pomocniczą (nieco gadatliwą, tho).
Oto przykład tego, jak nowe funkcjonalne zaimportowane zestawienie są IMHO mocniejsze i bardziej eleganckie niż stare imperatywne.
źródło
int start
iint count
. Twoje przykłady nie będą działać tak, jak zostały napisane. Piszesz tak, jakby drugi argument byłint end
. Na przykład -Enumerable.Range(11,20)
dałoby 20 liczb zaczynających się od 11, a nie liczb od 11 do 20.Enumerable.Range(11,20).Contains(c)
jest to odpowiednikfor(int i = 11; i < 21; ++i){ if (i == c) return true; } return false;
Jeśli miałeś duży zasięg, zajęłoby to dużo czasu, a samo użycie>
i<
byłoby szybkie i stałe.MySwitchWithEnumerable
Zwrotvoid
jest słabym pomysłem na tę sytuację. POWÓD: Przekształciłeśif-else
w szereg niezależnych instrukcji - które ukrywają zamiar, to znaczy, że wykluczają się one wzajemnie -action
wykonywana jest tylko jedna . Zamiast wrócićbool
z ciałemif (..) { action(); return true; } else return false;
Witryna nazywając następnie pokazuje intencję:if (MySwitchWithEnumerable(..)) else (MySwitchWithEnumerable(..));
. To jest lepsze. Jednak w tym prostym przypadku nie jest to już znacząca poprawa w stosunku do oryginalnej wersji.Oto kompletne rozwiązanie C # 7 ...
Działa również z łańcuchami ...
źródło
Poniższy kod nie działa:
Jedynym sposobem na to jest:
Kod, którego szukasz, działa w języku Visual Basic, w którym możesz łatwo wstawiać zakresy ... w
none
opcjiswitch
instrukcji lubif else
bloków wygodnych, sugerowałbym, aby w bardzo ekstremalnym momencie utworzyć .dll z Visual Basic i zaimportować z powrotem do twojego projektu w C #.Uwaga: odpowiednikiem przełącznika w Visual Basic jest
Select Case
.źródło
Inną opcją byłoby użycie procedury. Jeśli wszystkie przypadki 1-3 wykonują tę samą logikę, zapisz ją w procedurze i wywołaj dla każdej sprawy. Wiem, że tak naprawdę nie pozbywa się instrukcji, ale wdraża dobry styl i ogranicza obsługę do minimum .....
[Edytuj] Dodano alternatywną implementację, aby dopasować oryginalne pytanie ... [/ Edytuj]
Alt
źródło
Jednym z mniej znanych aspektów przełącznika w języku C # jest to, że zależy on od operatora =, a ponieważ można go zastąpić, możesz mieć coś takiego:
źródło
gcc implementuje rozszerzenie języka C do obsługi zakresów sekwencyjnych:
Edycja : Właśnie zauważyłem znacznik C # w pytaniu, więc prawdopodobnie odpowiedź gcc nie pomaga.
źródło
W C # 7 mamy teraz Dopasowywanie Wzorów, dzięki czemu możesz zrobić coś takiego:
źródło
Właściwie nie podoba mi się również polecenie GOTO, ale jest ono w oficjalnych materiałach Microsoft i tutaj są dozwolone wszystkie składnie.
Jeśli osiągnięty zostanie punkt końcowy listy instrukcji sekcji przełączania, wystąpi błąd kompilacji. Jest to znane jako zasada „bez upadku”. Przykład
jest ważny, ponieważ żadna sekcja przełącznika nie ma osiągalnego punktu końcowego. W przeciwieństwie do C i C ++, wykonanie sekcji przełącznika nie może „przejść” do następnej sekcji przełącznika, a przykład
powoduje błąd czasu kompilacji. Jeśli po wykonaniu sekcji przełącznika ma nastąpić wykonanie innej sekcji przełącznika, należy użyć jawnego przypadku goto lub instrukcji goto default:
Dozwolone jest stosowanie wielu etykiet w sekcji przełączników. Przykład
Uważam, że w tym konkretnym przypadku można użyć GOTO i jest to właściwie jedyny sposób na upadek.
Źródło: http://msdn.microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx
źródło
goto
prawie zawsze można tego uniknąć (choć nie uważam tego za „okropny” - pełni określoną, ustrukturyzowaną rolę). W twoim przykładzie, ponieważ umieściłeś ciała w funkcjach (to dobrze), przypadek 0 może się staćCaseZero(); CaseZeroOrOne(); break;
. Niegoto
wymaganeWygląda na to, że włożono wiele pracy w znalezienie sposobów na uzyskanie jednej z najmniej używanych C # składni, aby wyglądały lepiej lub działały lepiej. Osobiście uważam, że instrukcja switch jest rzadko warta użycia. Zdecydowanie zalecam przeanalizowanie danych, które testujesz, i oczekiwanych wyników końcowych.
Powiedzmy na przykład, że chcesz szybko przetestować wartości w znanym zakresie, aby sprawdzić, czy są to liczby pierwsze. Chcesz uniknąć marnotrawstwa obliczeń i możesz znaleźć listę liczb pierwszych w zakresie, który chcesz online. Możesz użyć ogromnej instrukcji switch, aby porównać każdą wartość ze znanymi liczbami pierwszymi.
Lub możesz po prostu stworzyć mapę tablic liczb pierwszych i uzyskać natychmiastowe wyniki:
Może chcesz sprawdzić, czy znak w ciągu jest szesnastkowy. Możesz użyć nieprzyjemnej i nieco dużej instrukcji switch.
Możesz też użyć wyrażeń regularnych do przetestowania znaku lub użyć funkcji IndexOf do wyszukania znaku w ciągu znanych liter szesnastkowych:
Powiedzmy, że chcesz wykonać jedną z 3 różnych akcji w zależności od wartości, która będzie w zakresie od 1 do 24. Sugerowałbym użycie zestawu instrukcji JEŻELI. A jeśli stanie się to zbyt skomplikowane (Lub liczby byłyby większe, takie jak 5 różnych akcji w zależności od wartości z zakresu od 1 do 90), użyj enum, aby zdefiniować akcje i stworzyć mapę tablicową wyliczeń. Wartość zostanie następnie wykorzystana do zindeksowania do mapy tablic i uzyskania wyliczenia żądanej akcji. Następnie użyj małego zestawu instrukcji IF lub bardzo prostej instrukcji switch, aby przetworzyć wynikową wartość wyliczenia.
Zaletą mapy tablic, która konwertuje zakres wartości na działania, jest to, że można go łatwo zmienić za pomocą kodu. Dzięki kodowi przewodowemu nie można łatwo zmienić zachowania w czasie wykonywania, ale z mapą tablic jest to łatwe.
źródło
Aby dodać do rozmowy, korzystając z .NET 4.6.2, mogłem również wykonać następujące czynności. Przetestowałem kod i zadziałał dla mnie.
Możesz także wykonać wiele instrukcji „LUB”, takich jak poniżej:
Możesz także sprawdzić, czy pasuje do wartości w tablicy:
źródło
Jeśli masz bardzo dużą liczbę łańcuchów znaków (lub dowolnego innego typu), które wszystkie robią to samo, polecam użycie listy łańcuchów w połączeniu z właściwością string.Contains.
Więc jeśli masz dużą instrukcję przełączającą taką:
Możesz zamienić go na taką
if
instrukcję:Skaluje się dobrze dla dowolnej liczby przypadków ciągów.
źródło
Myślę, że ten jest lepszy w C # 7 lub wyższej.
Możesz także sprawdzić zakres w przypadku przełącznika C #: przypadek przełącznika: czy mogę użyć zakresu zamiast jednej liczby lub jeśli chcesz zrozumieć podstawy przypadku przełącznika C #
źródło
W tym celu użyłbyś instrukcji goto. Jak na przykład:
źródło
goto
. Co gorsza, jest to całkowicie niepotrzebne użyciegoto
, ponieważ oryginalna składnia podana przez OP działa. Pytanie brzmiało, czy istnieje bardziej zwięzły sposób na podanie alternatywnych przypadków. Jak ludzie odpowiedzieli wiele lat wcześniej , tak, jest - jeśli chcesz umieścić kilka skrzynek w jednym wierszucase 1: case 2:
i jeśli pozwala na to automatyczny styl edytora.