Czy jest jakaś znacząca różnica między używaniem if / else i przełączaniem w C #?

219

Jaka jest korzyść / wada używania switchwyciągu w porównaniu do an if/elsew C #. Nie mogę sobie wyobrazić, żeby istniała tak duża różnica, inna niż może wygląd twojego kodu.

Czy jest jakiś powód, dla którego wynikowa wydajność IL lub powiązane środowisko uruchomieniowe byłoby diametralnie różne?

Powiązane: Co jest szybsze, przełącza ciąg lub na inny typ?

Matthew M. Osborn
źródło
3
To pytanie jest interesujące teoretycznie tylko dla większości programistów, chyba że często powtarzasz JEDEN BILLION razy. (Następnie użyj instrukcji przełączania i przejdź z 48 do 43 sekund ...) Lub słowami Donalda Knutha: „Powinniśmy zapomnieć o małej wydajności, powiedzmy w około 97% przypadków: przedwczesna optymalizacja jest źródłem wszelkiego zła” en.wikipedia.org/wiki/Program_optimization#When_to_optimize
Ojciec
Często używam if / else zamiast switcha ze względu na dziwny wspólny zakres przełączania.
Josh

Odpowiedzi:

341

Instrukcja SWITCH produkuje tylko ten sam zestaw co IFs w trybie debugowania lub zgodności. W wydaniu zostanie on skompilowany do tabeli skoków (za pomocą instrukcji MSIL „switch”) - czyli O (1).

C # (w przeciwieństwie do wielu innych języków) pozwala również na włączenie stałych ciągów - i działa to nieco inaczej. Oczywiście nie jest praktyczne budowanie tabel skoków dla ciągów o dowolnej długości, więc najczęściej taki przełącznik będzie kompilowany w stos IF.

Ale jeśli liczba warunków jest wystarczająco duża, aby pokryć koszty ogólne, kompilator C # utworzy obiekt HashTable, zapełni go stałymi ciągami i przeprowadzi wyszukiwanie w tej tabeli, a następnie skok. Hashtable lookup nie jest ściśle O (1) i ma zauważalne stałe koszty, ale jeśli liczba etykiet wielkości liter jest duża, będzie to znacznie szybsze niż w porównaniu do każdej stałej łańcucha w IF.

Podsumowując, jeśli liczba warunków jest większa niż 5, wybierz SWITCH zamiast IF, w przeciwnym razie użyj tego, co wygląda lepiej.

ima
źródło
1
Czy jesteś pewien, że kompilator C # wygeneruje tablicę skrótów? Punkt, który wspomniałem o tabeli skrótów w powyższej dyskusji na temat komentarzy, dotyczył natywnych kompilatorów, a nie kompilatora C #. Jakiego progu używa kompilator C # do utworzenia tabeli skrótów?
Scott Wiśniewski
8
Myślę, że około dziesięciu. 20, aby być po bezpiecznej stronie. A tak przy okazji, mój gniew nie jest tobą, ale na ludziach wygłaszających głos i przyjmujących.
ima
48
Trochę eksperymentów sugeruje liczenie <= 6: „if”; count> = 7: słownik. Tak jest w przypadku kompilatora MS .NET 3.5 C # - oczywiście może on zmieniać wersje i dostawców.
Jon Skeet
37
Hej, jestem ci winien przeprosiny. Przepraszam za bycie kościaną głową.
Scott Wisniewski
Czy dla praktycznych zastosowań w większości przypadków istnieje jakaś rzeczywista różnica w świecie? Uważam, że instrukcje przełączników w języku C # są nieparzyste, ich składnia nie jest podobna do niczego innego i stwierdzam, że sprawiają, że mój kod jest mniej czytelny, czy warto zawracać sobie głowę używaniem instrukcji przełączania, czy powinienem po prostu programować z innymi ifs i tylko przyjść wrócić i wymienić je, jeśli napotkam wąskie gardła wydajności?
Jason Masters
54

Ogólnie (biorąc pod uwagę wszystkie języki i wszystkie kompilatory) instrukcja switch MOŻE CZASEM być bardziej wydajna niż instrukcja if / else, ponieważ kompilator łatwo generuje tabele skoku z instrukcji switch. Można zrobić to samo dla instrukcji if / else z odpowiednimi ograniczeniami, ale jest to o wiele trudniejsze.

W przypadku C # jest to również prawdą, ale z innych powodów.

Przy dużej liczbie ciągów znacząca przewaga wydajności polega na użyciu instrukcji switch, ponieważ kompilator użyje tabeli skrótów do wdrożenia skoku.

Przy niewielkiej liczbie ciągów wydajność między nimi jest taka sama.

Jest tak, ponieważ w takim przypadku kompilator C # nie generuje tabeli skoków. Zamiast tego generuje MSIL, który jest równoważny blokom IF / ELSE.

Istnieje instrukcja MSIL „instrukcja przełączania”, która po wysłaniu użyje tabeli skoków do implementacji instrukcji przełączania. Działa jednak tylko z typami liczb całkowitych (to pytanie dotyczy ciągów znaków).

W przypadku niewielkiej liczby łańcuchów kompilator bardziej efektywnie generuje bloki IF / ELSE, niż korzysta z tabeli skrótów.

Kiedy pierwotnie to zauważyłem, założyłem, że ponieważ bloki IF / ELSE były używane z małą liczbą łańcuchów, to kompilator dokonał tej samej transformacji dla dużej liczby łańcuchów.

To było ŹLE. „IMA” był na tyle uprzejmy, aby mi to wskazać (cóż ... nie był do tego miły, ale miał rację, a ja się myliłem, co jest ważną częścią)

Przyjąłem również założenie, że brak instrukcji „przełączania” w MSIL (pomyślałem, że jeśli istnieje prymityw przełącznika, to dlaczego nie używają go z tabelą skrótów, więc nie może istnieć prymityw przełącznika). ...) To było zarówno złe, jak i niesamowicie głupie z mojej strony. „IMA” ponownie mi to wskazało.

Dokonałem tutaj aktualizacji, ponieważ jest to najwyżej oceniany post i zaakceptowana odpowiedź.

Zrobiłem to jednak Wiki Wiki, ponieważ uważam, że nie zasługuję na REP za to, że się mylę. Jeśli masz szansę, zagłosuj na wpis „ima”.

Scott Scott Wiśniewski
źródło
3
W MSIL znajduje się prymityw przełączania, a instrukcje c # kompilują się w generalnie wyszukiwania typu C. W pewnych okolicznościach (platforma docelowa, przełączniki cl itp.) Przełącznik może zostać rozszerzony na IF podczas kompilacji, ale jest to tylko awaryjna miara zgodności.
ima
6
Wszystko, co mogę zrobić, to przeprosić za głupi błąd. Uwierz mi, czuję się głupio z tego powodu. Poważnie, myślę, że to wciąż najlepsza odpowiedź. W natywnych kompilatorach możliwe jest użycie tabeli skrótów do implementacji skoku, więc nie jest to żadna strasznie zła rzecz. Popełniłem jeden błąd.
Scott Wisniewski
9
ima, jeśli są błędy, wskaż je. Wygląda na to, że Scott z przyjemnością poprawi wpis. Jeśli nie, zrobią to inni, którzy uzyskali umiejętność poprawienia odpowiedzi. To jedyny sposób, w jaki taka strona będzie działać i wydaje się, że ogólnie działa. Lub weź piłkę i idź do domu :)
jwalkerjr
2
@Scott: Zachęcam do edycji drugiego i trzeciego akapitu, aby wyraźnie określić „dla ciągów”. Ludzie mogą nie czytać aktualizacji na dole.
Jon Skeet
4
@ima Jeśli uważasz, że odpowiedź jest obiektywnie nieprawidłowa, edytuj ją, aby była poprawna. Dlatego każdy może edytować odpowiedzi.
Miles Rout
18

Trzy powody, dla których wolisz switch:

  • Kompilator celujący w natywny kod często kompiluje instrukcję switch w jedną gałąź warunkową plus skok pośredni, podczas gdy sekwencja ifs wymaga sekwencji gałęzi warunkowych . W zależności od gęstości przypadków napisano bardzo wiele wyuczonych artykułów na temat efektywnego kompilowania zestawień przypadków; niektóre są połączone ze strony kompilatora lcc . (Lcc miał jeden z bardziej innowacyjnych kompilatorów do przełączników).

  • Instrukcja switch jest wyborem spośród wzajemnie wykluczających się alternatyw, a składnia przełącznika czyni ten przepływ sterowania bardziej przejrzystym dla programisty niż gniazdo instrukcji if-then-else.

  • W niektórych językach, w tym zdecydowanie ML i Haskell, kompilator sprawdza, czy pominięto jakieś przypadki . Uważam tę funkcję za jedną z głównych zalet ML i Haskell. Nie wiem czy C # może to zrobić.

Anegdota: na wykładzie, który wygłosił po otrzymaniu nagrody za całokształt twórczości, usłyszałem, jak Tony Hoare powiedział, że ze wszystkich rzeczy, które zrobił w swojej karierze, były trzy, z których był najbardziej dumny:

  • Wynalezienie Quicksort
  • Wymyślanie instrukcji switch (którą Tony nazwał caseinstrukcją)
  • Rozpoczęcie i zakończenie kariery w branży

Nie wyobrażam sobie życia bezswitch .

Norman Ramsey
źródło
16

Kompilator zoptymalizuje prawie wszystko do tego samego kodu z niewielkimi różnicami (Knuth, ktoś?).

Różnica polega na tym, że instrukcja switch jest czystsza niż piętnaście, jeśli w przeciwnym razie zestawione są razem.

Znajomi nie pozwalają znajomym układać instrukcji if-else.


źródło
13
„Przyjaciele nie pozwalają znajomym układać instrukcji if-else”. Powinieneś zrobić sprytny sitcker :)
Matthew M. Osborn
14

W rzeczywistości instrukcja switch jest bardziej wydajna. Kompilator zoptymalizuje go do tabeli wyszukiwania, w której nie można tego zrobić za pomocą instrukcji if / else. Wadą jest to, że instrukcja switch nie może być używana z wartościami zmiennymi.
Nie możesz zrobić:

switch(variable)
{
   case someVariable
   break;
   default:
   break;
}

to musi być

switch(variable)
{
  case CONSTANT_VALUE;
  break;
  default:
  break;
}
kemiller2002
źródło
1
czy masz jakieś liczby? Jestem ciekawy, jak dobrze kompilator może zoptymalizować swtich oświadczenie w stosunku do If / Else
Matthew M. Osborn
tak, uważam, że instrukcja switch zawsze optymalizuje się do O (1), gdzie instrukcja if else będzie O (n), gdzie n jest pozycją poprawnej wartości w instrukcjach if / else if.
kemiller2002
W przypadku C # to nie jest prawda, zobacz mój post poniżej, aby uzyskać więcej informacji.
Scott Wiśniewski
Nie jestem tego całkowicie pewien, ale nie mogę znaleźć informacji w książce, przysięgam, że ją znalazłem. Jesteś pewien, że nie patrzysz na kod MSIL bez optymalizacji. Nie utworzy tabeli skoków, chyba że skompilujesz z włączoną optymalizacją.
kemiller2002
Kompilowałem zarówno w trybie debugowania, jak i sprzedaży detalicznej, aw obu przypadkach generuje bloki if / else. Czy na pewno książka, którą oglądałeś, mówi o C #? Książka była prawdopodobnie książką kompilatora lub książką o C lub C ++
Scott Wisniewski
14

Nie widziałem, aby ktokolwiek podniósł (oczywisty?) Punkt, że domniemana przewaga wydajności instrukcji switch zależy od tego, czy różne przypadki są w przybliżeniu jednakowo prawdopodobne. W przypadkach, w których jedna (lub kilka) wartości jest znacznie bardziej prawdopodobna, drabina „jeśli-to-inaczej” może być znacznie szybsza, zapewniając najpierw sprawdzenie najczęstszych przypadków:

Na przykład:

if (x==0) then {
  // do one thing
} else if (x==1) {
  // do the other thing
} else if (x==2) {
  // do the third thing
}

vs

switch(x) {
  case 0: 
         // do one thing
         break;
  case 1: 
         // do the other thing
         break;
  case 2: 
         // do the third thing
         break;
}

Jeśli x wynosi zero w 90% przypadków, kod „jeśli-inaczej” może być dwa razy szybszy niż kod oparty na przełączaniu. Nawet jeśli kompilator zmieni „przełącznik” w coś w rodzaju sprytnego goto sterowanego tabelą, nadal nie będzie tak szybki, jak po prostu sprawdzanie zera.

Mark Bessey
źródło
3
Bez przedwczesnej optymalizacji! Ogólnie rzecz biorąc, jeśli masz więcej niż kilka przypadków i są one switchkompatybilne, switchinstrukcja jest lepsza (bardziej czytelna, czasem szybsza). Jeśli wiesz, że jeden przypadek jest znacznie bardziej prawdopodobny, możesz go wyciągnąć, aby utworzyć konstrukcję if- else- switchi jeśli jest to wymiernie szybsze , zostaw to w. (Powtórz, jeśli to konieczne.) IMO jest nadal dość czytelne. Jeśli switchdegeneruje się i staje się zbyt mały, zastąpienie wyrażenia regularnego wykona większość pracy przekształcania go w else ifłańcuch.
nikt
6
Pierwotne pytanie (trzy lata temu!) Właśnie zadawało zalety i wady między if / else a przełączaniem. To jest jeden przykład. Osobiście widziałem, że tego rodzaju optymalizacja ma znaczącą różnicę w czasie wykonywania procedury.
Mark Bessey,
7

często będzie wyglądać lepiej - tzn. łatwiej będzie zrozumieć, co się dzieje. Biorąc pod uwagę, że poprawa wydajności będzie co najwyżej wyjątkowo minimalna, najważniejszą różnicą jest widok kodu.

Tak więc, jeśli if / else wygląda lepiej, użyj go, w przeciwnym razie użyj instrukcji switch.

gbjbaanb
źródło
4

Temat poboczny, ale często martwię się (i częściej widzę) if/ elsei switchinstrukcja staje się zbyt duża w zbyt wielu przypadkach. Często przeszkadzają w utrzymaniu.

Powszechni sprawcy to:

  1. Robienie zbyt wiele wewnątrz wielu instrukcji if
  2. Więcej stwierdzeń przypadków, niż można po ludzku przeanalizować
  3. Zbyt wiele warunków w ocenie if, aby wiedzieć, czego się szuka

Naprawić:

  1. Refaktoryzacja wyciągu z metody.
  2. Użyj słownika ze wskaźnikami metod zamiast wielkości liter lub użyj IoC, aby zwiększyć konfigurowalność. Pomocne mogą być również fabryki metod.
  3. Wyodrębnij warunki według ich własnej metody
Chris Brandsma
źródło
4

Zgodnie z tym linkiem porównanie testu iteracji IF vs Switch za pomocą instrukcji switch i if jest jak dla 1 000 000 000 iteracji, czas potrzebny na instrukcję Switch = 43.0s i przez If If = 48.0s

To jest dosłownie 20833333 iteracji na sekundę, więc czy naprawdę powinniśmy się bardziej skoncentrować,

PS: Aby poznać różnicę wydajności dla małej listy warunków.

Bretfort
źródło
To dla mnie gwoździe.
Greg Gum
3

Jeśli używasz tylko instrukcji if lub else, podstawowe rozwiązanie używa porównania? operator

(value == value1) ? (type1)do this : (type1)or do this;

Możesz zrobić lub rutynowo w przełączniku

switch(typeCode)
{
   case TypeCode:Int32:
   case TypeCode.Int64:
     //dosomething here
     break;
   default: return;
}
Robert W.
źródło
2

To tak naprawdę nie odpowiada na twoje pytanie, ale biorąc pod uwagę, że między skompilowanymi wersjami będzie niewielka różnica, zachęcam do napisania kodu w sposób, który najlepiej opisuje twoje zamiary. Nie tylko jest większa szansa, że ​​kompilator zrobi to, czego oczekujesz, ale ułatwi innym utrzymanie Twojego kodu.

Jeśli twoim zamiarem jest rozgałęzienie programu na podstawie wartości jednej zmiennej / atrybutu, wówczas instrukcja switch najlepiej reprezentuje ten zamiar.

Jeśli Twoim celem jest rozgałęzienie programu w oparciu o różne zmienne / atrybuty / warunki, to łańcuch if / else if najlepiej reprezentuje ten zamiar.

Przyznaję, że cody ma rację, że ludzie zapominają o komendzie break, ale prawie tak często widzę, że ludzie robią skomplikowane, jeśli bloki, w których źle {} się mylą, więc wiersze, które powinny znajdować się w instrukcji warunkowej, nie są. Jest to jeden z powodów, dla których zawsze umieszczam {} w moich instrukcjach if, nawet jeśli jest w nich jedna linia. Nie tylko łatwiej jest czytać, ale jeśli muszę dodać kolejną linię warunkową, nie mogę zapomnieć o jej dodaniu.

dj_segfault
źródło
2

Pytanie o zainteresowanie To pojawiło się kilka tygodni temu w pracy i znaleźliśmy odpowiedź, pisząc przykładowy fragment i przeglądając go w .NET Reflector (reflektor jest niesamowity !! uwielbiam go).

Oto, co odkryliśmy: Poprawna instrukcja switch dla czegoś innego niż ciąg jest kompilowana do IL jako instrukcja switch. Jednak JEŻELI jest to ciąg znaków, jest przepisywany jako if / else if / else w IL. W naszym przypadku chcieliśmy wiedzieć, w jaki sposób instrukcje switch porównują ciągi znaków, np. Rozróżnia wielkość liter itp., A reflektor szybko dał nam odpowiedź. Warto było to wiedzieć.

Jeśli chcesz zrobić rozróżniana porównać na sznurkach wtedy mógłby użyć instrukcji switch, gdyż jest szybszy niż wykonywanie String.Compare w if / else. (Edycja: Czytaj, co jest szybsze, włącz ciąg lub ifif na typ? W przypadku niektórych faktycznych testów wydajności) Jednak jeśli chcesz zrobić bez rozróżniania wielkości liter, lepiej jest użyć if / else, ponieważ wynikowy kod nie jest ładny.

switch (myString.ToLower())
{
  // not a good solution
}

Najlepszą ogólną zasadą jest używanie instrukcji switch, jeśli ma to sens (poważnie), np .:

  • poprawia czytelność twojego kodu
  • porównujesz zakres wartości (zmiennoprzecinkowy, int) lub wyliczenie

Jeśli potrzebujesz manipulować wartością, aby wprowadzić ją do instrukcji switch (utwórz zmienną tymczasową, na którą chcesz się przełączyć), prawdopodobnie powinieneś użyć instrukcji kontrolnej if / else.

Aktualizacja:

Właściwie lepiej jest przekonwertować ciąg na wielkie litery (np. ToUpper()), Ponieważ najwyraźniej istnieją dalsze optymalizacje, które kompilator just-in-time może zrobić w porównaniu z ToLower(). Jest to mikrooptymalizacja, jednak w ciasnej pętli może się przydać.


Mała uwaga dodatkowa:

Aby poprawić czytelność instrukcji switch, spróbuj:

  • umieść najbardziej prawdopodobną gałąź na pierwszym miejscu, tj. najbardziej dostępną
  • jeśli wszystkie mogą wystąpić, należy wymienić je w kolejności alfabetycznej, aby łatwiej je znaleźć.
  • nigdy nie używaj domyślnego catch-all dla ostatniego pozostałego warunku, jest to leniwe i spowoduje problemy w późniejszym okresie życia kodu.
  • użyj domyślnego catch-all, aby potwierdzić nieznany warunek, nawet jeśli jest bardzo mało prawdopodobne, że kiedykolwiek wystąpi. do tego służą twierdzenia.
Dennis
źródło
W wielu przypadkach użycie ToLower () jest właściwym rozwiązaniem, szczególnie jeśli jest wiele przypadków i generowana jest tablica skrótów.
Blaisorblade,
„Jeśli musisz manipulować wartością, aby wprowadzić ją do instrukcji switch (utwórz zmienną tymczasową, na którą chcesz się przełączyć), prawdopodobnie powinieneś użyć instrukcji kontrolnej if / else.” - Dobra rada, dzięki.
Sneakyness,
2

Instrukcja switch jest zdecydowanie szybsza niż if if else. Istnieje test prędkości dostarczony na nim przez BlackWasp

http://www.blackwasp.co.uk/SpeedTestIfElseSwitch.aspx

--Sprawdź to

Ale zależy w dużej mierze od możliwości, które próbujesz uwzględnić, ale staram się używać instrukcji switch, gdy tylko jest to możliwe.

pocenie się
źródło
1

Myślę, że nie tylko język C #, ale wszystkie języki oparte na języku C: ponieważ przełącznik ogranicza się do stałych, możliwe jest wygenerowanie bardzo wydajnego kodu przy użyciu „tablicy skoków”. Przypadek C jest naprawdę dobrym, starym obliczonym GOTO przez FORTRAN, ale przypadek C # wciąż testuje względem stałej.

Nie jest tak, że optymalizator będzie mógł stworzyć ten sam kod. Rozważ np.

if(a == 3){ //...
} else if (a == 5 || a == 7){ //...
} else {//...
}

Ponieważ są to złożone wartości logiczne, wygenerowany kod musi obliczyć wartość i skrót. Teraz rozważ odpowiednik

switch(a){
   case 3: // ...
    break;
   case 5:
   case 7: //...
    break;
   default: //...
}

Można to skompilować

BTABL: *
B3:   addr of 3 code
B5:
B7:   addr of 5,7 code
      load 0,1 ino reg X based on value
      jump indirect through BTABL+x

ponieważ domyślnie informujesz kompilator, że nie musi on obliczać testów OR i testów równości.

Charlie Martin
źródło
Nie ma powodu, dla którego dobry optymalizator nie może obsłużyć pierwszego kodu, o ile optymalizacja jest zaimplementowana. „Kompilator nie może zoptymalizować” zależy tylko od różnic semantycznych, które tylko człowiek może pogodzić (tzn. Jeśli wywoływane jest f (), nie wie, że f () zawsze zwraca 0 lub 1).
Blaisorblade,
0

Mój profesor cs zasugerował, aby nie zmieniać wypowiedzi, ponieważ tak często ludzie zapominali o przerwie lub używali jej nieprawidłowo. Nie mogę sobie przypomnieć dokładnie tego, co powiedział, ale coś podobnego do tego, że patrząc na niektóre podstawowe kody, które pokazały przykłady instrukcji switch (lata temu), zawierało w sobie mnóstwo błędów.


źródło
Naprawdę nie jest to problem w języku C #. Zobacz: stackoverflow.com/questions/174155/ ... ... a także przeczytaj stackoverflow.com/questions/188461/..., aby dowiedzieć się, dlaczego życie w strachu może nie być najlepszą polityką ...
Shog9
0

Coś, co właśnie zauważyłem, to możliwość łączenia instrukcji if / else i przełączania instrukcji! Bardzo przydatne, gdy trzeba sprawdzić warunki wstępne.

if (string.IsNullOrEmpty(line))
{
    //skip empty lines
}
else switch (line.Substring(0,1))
{
    case "1":
        Console.WriteLine(line);
        break;
    case "9":
        Console.WriteLine(line);
        break;
    default:
        break;
}
Nawet Mien
źródło
3
Wiem, że to stare, ale myślę, że technicznie nic nie „łączysz”. Za każdym razem, gdy masz „else” bez nawiasów klamrowych, następna instrukcja zostanie wykonana. Ta instrukcja może być instrukcją jednowierszową, zwykle pokazywaną z wcięciem w następnym wierszu, lub instrukcją złożoną, taką jak w przypadku if, switch, using, lock itp. Innymi słowy, możesz mieć „else if”, „ else switch ”,„ else using ”itp. Powiedziawszy to, podoba mi się to, jak wygląda i prawie celowo. (Oświadczenie: Nie próbowałem tych wszystkich, więc MOGĘ się mylić!)
Nelson Rothermel
Nelson, masz 100% racji. Zrozumiałem, dlaczego tak się dzieje po opublikowaniu tej odpowiedzi.
Nawet Mien
0

Myślę, że zmiana jest szybsza niż wtedy, gdy warunki takie jak sprawdzają, czy istnieje program taki jak:

Napisz program, aby wprowadzić dowolną liczbę (od 1 do 99) i sprawdź, w której szczelinie a) 1 - 9, następnie 1) b - 11 - 19, a następnie 2 c) 21-29, a następnie 3 i tak dalej aż do 89- 99

Następnie włącz, jeśli musisz stworzyć wiele warunków, ale skrzynka przełącznika syna musisz po prostu wpisać

Przełącznik (no / 10)

i w przypadku 0 = 1-9, przypadek 1 = 11-19 i tak dalej

będzie tak łatwo

Istnieje również wiele innych takich przykładów!

Społeczność
źródło
0

instrukcja switch jest w zasadzie porównaniem równości. Zdarzenie na klawiaturze ma wielką przewagę nad instrukcją switch, gdy ma łatwość pisania i odczytywania kodu, a wtedy instrukcja if elseif, brakując {nawiasu}, również może sprawiać problemy.

char abc;
switch(abc)
{
case a: break;
case b: break;
case c: break;
case d: break;
}

Instrukcja if elseif jest idealna dla więcej niż jednego rozwiązania, jeśli (AmountOfApples jest większa niż 5 i & AmountOfApples jest mniejsza niż 10) zapisz swoje jabłka, jeśli (AmountOfApples jest większe niż 10 || AmountOfApples == 100) sprzedaj jabłka. Nie piszę w języku c # lub c ++, ale nauczyłem się tego, zanim nauczyłem się języka Java i są to bliskie języki.

Geen
źródło
0

Jednym z możliwych wad instrukcji switch jest brak wielu warunków. Możesz mieć wiele warunków dla instrukcji if (else), ale nie wiele instrukcji z różnymi warunkami w przełączniku.

Instrukcje switch nie nadają się do operacji logicznych wykraczających poza proste równania / wyrażenia logiczne. Dla tych równań / wyrażeń logicznych jest on szczególnie odpowiedni, ale nie do innych operacji logicznych.

Masz dużo większą swobodę dzięki logice dostępnej w instrukcjach If, ale czytelność może ucierpieć, jeśli instrukcja If stanie się nieporęczna lub będzie źle obsługiwana.

Oba mają miejsce w zależności od kontekstu tego, z czym masz do czynienia.

Neil Meyer
źródło