Gibt es einen signifikanten Unterschied zwischen der Verwendung von if / else und switch-case in C #?

219

Was ist der Vorteil / Nachteil der Verwendung einer switchAnweisung gegenüber einer if/elsein C # ? Ich kann mir nicht vorstellen, dass es einen so großen Unterschied gibt, außer vielleicht dem Aussehen Ihres Codes.

Gibt es einen Grund, warum die resultierende IL oder die damit verbundene Laufzeitleistung radikal anders wäre?

Verwandte: Was ist schneller, String einschalten oder sonst Typ?

Matthew M. Osborn
quelle
3
Diese Frage ist theoretisch nur für die Mehrheit der Entwickler interessant, es sei denn, Sie wiederholen häufig eine Milliarde Mal. (Verwenden Sie dann eine switch-Anweisung und gehen Sie von 48 auf 43 Sekunden ...) Oder mit den Worten von Donald Knuth: "Wir sollten kleine Wirkungsgrade vergessen, sagen wir etwa 97% der Zeit: Vorzeitige Optimierung ist die Wurzel allen Übels." en.wikipedia.org/wiki/Program_optimization#When_to_optimize
Vater
Ich benutze oft if / else anstelle von switch, weil der Wonky-Bereich von switch gemeinsam genutzt wird.
Josh

Antworten:

341

Die SWITCH-Anweisung erzeugt nur dieselbe Assembly wie IFs im Debug- oder Kompatibilitätsmodus. In der Version wird es in die Sprungtabelle kompiliert (über die MSIL-Anweisung 'switch') - das ist O (1).

C # ermöglicht (im Gegensatz zu vielen anderen Sprachen) auch das Einschalten von String-Konstanten - und das funktioniert etwas anders. Es ist offensichtlich nicht praktikabel, Sprungtabellen für Zeichenfolgen beliebiger Länge zu erstellen, daher wird ein solcher Schalter meistens zu einem Stapel von IFs kompiliert.

Wenn die Anzahl der Bedingungen jedoch groß genug ist, um Overheads abzudecken, erstellt der C # -Compiler ein HashTable-Objekt, füllt es mit Zeichenfolgenkonstanten und führt eine Suche in dieser Tabelle durch, gefolgt von einem Sprung. Die Suche nach Hashtabellen ist nicht unbedingt O (1) und verursacht spürbare konstante Kosten. Wenn jedoch die Anzahl der Fallbezeichnungen groß ist, ist sie erheblich schneller als der Vergleich mit jeder Zeichenfolgenkonstante in IFs.

Um es zusammenzufassen: Wenn die Anzahl der Bedingungen mehr als 5 beträgt, ziehen Sie SWITCH gegenüber IF vor, andernfalls verwenden Sie das, was besser aussieht.

ima
quelle
1
Sind Sie sicher, dass der C # -Compiler eine Hash-Tabelle erstellt? Der Punkt, den ich in unserer obigen Kommentardiskussion über die Hash-Tabelle gemacht habe, betraf native Compiler, nicht den C # -Compiler. Welchen Schwellenwert verwendet der C # -Compiler, um eine Hash-Tabelle zu erstellen?
Scott Wisniewski
8
Gegen zehn denke ich. 20 um auf der sicheren Seite zu sein. Und übrigens, meine Wut sind nicht Sie, sondern die Menschen, die abstimmen und akzeptieren.
Ima
48
Ein bisschen experimentieren schlägt count <= 6 vor: "if"; count> = 7: Wörterbuch. Das ist mit dem MS .NET 3.5 C # -Compiler möglich - er kann natürlich zwischen Versionen und Anbietern wechseln.
Jon Skeet
37
Hey, ich schulde dir eine Entschuldigung. Tut mir leid, dass ich ein Knochenkopf bin.
Scott Wisniewski
Gibt es für praktische Anwendungen die meiste Zeit einen Unterschied in der realen Welt? Ich finde switch-Anweisungen in C # seltsam, ihre Syntax ist mit nichts anderem vergleichbar und ich finde, dass sie meinen Code weniger lesbar machen, lohnt es sich, switch-Anweisungen zu verwenden, oder sollte ich einfach mit else ifs programmieren und nur kommen zurück und ersetzen Sie sie, wenn ich Leistungsengpässe stoße?
Jason Masters
54

Im Allgemeinen (unter Berücksichtigung aller Sprachen und aller Compiler) kann eine switch-Anweisung manchmal effizienter sein als eine if / else-Anweisung, da es für einen Compiler einfach ist, Sprungtabellen aus switch-Anweisungen zu generieren. Es ist möglich, dasselbe für if / else-Anweisungen zu tun, wenn entsprechende Einschränkungen gegeben sind, aber das ist viel schwieriger.

Im Fall von C # gilt dies auch, jedoch aus anderen Gründen.

Bei einer großen Anzahl von Zeichenfolgen bietet die Verwendung einer switch-Anweisung einen erheblichen Leistungsvorteil, da der Compiler eine Hash-Tabelle verwendet, um den Sprung zu implementieren.

Mit einer kleinen Anzahl von Zeichenfolgen ist die Leistung zwischen den beiden gleich.

Dies liegt daran, dass der C # -Compiler in diesem Fall keine Sprungtabelle generiert. Stattdessen wird MSIL generiert, das IF / ELSE-Blöcken entspricht.

Es gibt eine MSIL-Anweisung "switch statement", die beim Jitting eine Sprungtabelle verwendet, um eine switch-Anweisung zu implementieren. Es funktioniert jedoch nur mit ganzzahligen Typen (diese Frage fragt nach Zeichenfolgen).

Für eine kleine Anzahl von Zeichenfolgen ist es für den Compiler effizienter, IF / ELSE-Blöcke zu generieren, als eine Hash-Tabelle zu verwenden.

Als ich dies ursprünglich bemerkte, ging ich davon aus, dass der Compiler dieselbe Transformation für eine große Anzahl von Zeichenfolgen durchführte, da IF / ELSE-Blöcke mit einer kleinen Anzahl von Zeichenfolgen verwendet wurden.

Das war falsch. 'IMA' war so freundlich, mich darauf aufmerksam zu machen (nun ... er war nicht freundlich, aber er hatte Recht und ich habe mich geirrt, was der wichtige Teil ist)

Ich habe auch eine knochenköpfige Annahme über das Fehlen einer "switch" -Anweisung in MSIL gemacht (ich dachte, wenn es ein switch-Grundelement gibt, warum verwenden sie es nicht mit einer Hash-Tabelle, also darf es kein switch-Grundelement geben. ...). Das war sowohl falsch als auch unglaublich dumm von meiner Seite. Wieder machte mich 'IMA' darauf aufmerksam.

Ich habe die Aktualisierungen hier vorgenommen, da dies der am höchsten bewertete Beitrag und die akzeptierte Antwort ist.

Ich habe es jedoch zum Community-Wiki gemacht, weil ich glaube, ich verdiene die REP nicht, weil ich falsch liege. Wenn Sie eine Chance bekommen, stimmen Sie bitte den Beitrag von 'ima' ab.

Scott Wisniewski
quelle
3
In MSIL gibt es ein Schalterprimitiv, und c # -Anweisungen werden zu einer allgemein C-ähnlichen Suche kompiliert. Unter bestimmten Umständen (Zielplattform, CL-Schalter usw.) kann der Schalter während der Kompilierung in IFs erweitert werden, dies ist jedoch nur eine Fallback-Kompatibilitätsmaßnahme.
ima
6
Ich kann mich nur dafür entschuldigen, dass ich einen dummen Fehler gemacht habe. Glauben Sie mir, ich fühle mich dumm darüber. Im Ernst, ich denke, es ist immer noch die beste Antwort. In nativen Compilern ist es möglich, eine Hash-Tabelle zu verwenden, um einen Sprung zu implementieren. Dies ist also keine schrecklich falsche Sache. Ich habe einen Fehler gemacht.
Scott Wisniewski
9
Ima, wenn es Fehler gibt, weisen Sie darauf hin. Klingt so, als würde Scott den Beitrag gerne korrigieren. Wenn nicht, tun dies andere, die die Fähigkeit zur Korrektur einer Antwort erreicht haben. Nur so funktioniert eine Site wie diese, und es scheint, dass sie im Allgemeinen funktioniert. Oder nimm deinen Ball und geh nach Hause :)
jwalkerjr
2
@Scott: Ich möchte Sie ermutigen, den zweiten und dritten Absatz so zu bearbeiten, dass explizit "für Zeichenfolgen" angegeben wird. Möglicherweise wird das Update unten nicht gelesen.
Jon Skeet
4
@ima Wenn Sie der Meinung sind, dass eine Antwort objektiv falsch ist, bearbeiten Sie sie so, dass sie korrekt ist. Deshalb kann jeder Antworten bearbeiten.
Miles Rout
18

Drei Gründe, das zu bevorzugen switch:

  • Ein Compiler, der auf nativen Code abzielt, kann häufig eine switch-Anweisung in einen bedingten Zweig plus einen indirekten Sprung kompilieren, während eine Folge von ifs eine Folge von bedingten Zweigen erfordert . Abhängig von der Dichte der Fälle wurden sehr viele gelernte Artikel darüber geschrieben, wie Fallaussagen effizient zusammengestellt werden können. Einige sind von der lcc-Compilerseite verlinkt . (Lcc hatte einen der innovativeren Compiler für Switches.)

  • Eine switch-Anweisung ist eine Auswahl unter sich gegenseitig ausschließenden Alternativen und die switch-Syntax macht diesen Steuerungsfluss für den Programmierer transparenter als ein Nest von if-then-else-Anweisungen.

  • In einigen Sprachen, darunter definitiv ML und Haskell, prüft der Compiler, ob Sie Fälle ausgelassen haben . Ich betrachte diese Funktion als einen der Hauptvorteile von ML und Haskell. Ich weiß nicht, ob C # das kann.

Eine Anekdote: Bei einem Vortrag, den er über die Auszeichnung für sein Lebenswerk hielt, hörte ich Tony Hoare sagen, dass es von all den Dingen, die er in seiner Karriere getan hat, drei gab, auf die er am stolzesten war:

  • Quicksort erfinden
  • Die switch-Anweisung erfinden (die Tony die nannte case Anweisung nannte)
  • Beginn und Ende seiner Karriere in der Industrie

Ich kann mir nicht vorstellen, ohne zu lebenswitch .

Norman Ramsey
quelle
16

Der Compiler wird so ziemlich alles mit geringfügigen Unterschieden in denselben Code optimieren (Knuth, irgendjemand?).

Der Unterschied besteht darin, dass eine switch-Anweisung sauberer als fünfzehn ist, wenn sonst Anweisungen aneinandergereiht sind.

Freunde lassen Freunde keine if-else-Anweisungen stapeln.


quelle
13
"Freunde lassen Freunde keine if-else-Anweisungen stapeln." Sie sollten einen Bumber Sitcker machen :)
Matthew M. Osborn
14

Tatsächlich ist eine switch-Anweisung effizienter. Der Compiler optimiert es in eine Nachschlagetabelle, in der es mit if / else-Anweisungen nicht möglich ist. Der Nachteil ist, dass eine switch-Anweisung nicht mit variablen Werten verwendet werden kann.
Sie können nicht tun:

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

Es muss sein

switch(variable)
{
  case CONSTANT_VALUE;
  break;
  default:
  break;
}
kemiller2002
quelle
1
Hast du irgendwelche Zahlen? Ich bin gespannt, wie gut ein Compiler eine swtich-Anweisung über ein If / Else optimieren kann
Matthew M. Osborn
Ja, ich glaube, eine switch-Anweisung wird immer auf O (1) optimiert, wobei eine if else-Anweisung O (n) ist, wobei n die Position des korrekten Werts in den if / else if-Anweisungen ist.
kemiller2002
Im Fall von C # ist dies nicht der Fall. Weitere Informationen finden Sie in meinem Beitrag unten.
Scott Wisniewski
Ich bin mir dessen nicht ganz sicher, aber ich kann keine Informationen in dem Buch finden, in dem ich es schwöre. Sind Sie sicher, dass Sie den MSIL-Code nicht ohne Optimierung betrachten? Die Sprungtabelle wird erst erstellt, wenn Sie mit aktivierter Optimierung kompilieren.
kemiller2002
Ich habe sowohl im Debug- als auch im Einzelhandelsmodus kompiliert und in beiden Fällen werden if / else-Blöcke generiert. Sind Sie sicher, dass das Buch, das Sie sich angesehen haben, über C # sprach? Das Buch war wahrscheinlich entweder ein Compiler-Buch oder ein Buch über C oder C ++
Scott Wisniewski
14

Ich habe niemanden gesehen, der den (offensichtlichen?) Punkt angesprochen hat, dass der vermeintliche Effizienzvorteil der switch-Anweisung davon abhängt, dass die verschiedenen Fälle ungefähr gleich wahrscheinlich sind. In Fällen, in denen einer (oder einige) der Werte viel wahrscheinlicher ist, kann die Wenn-Dann-Sonst-Leiter viel schneller sein, indem sichergestellt wird, dass die häufigsten Fälle zuerst überprüft werden:

Also zum Beispiel:

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;
}

Wenn x in 90% der Fälle Null ist, kann der "if-else" -Code doppelt so schnell sein wie der switchbasierte Code. Selbst wenn der Compiler den "Schalter" in eine Art cleveres tabellengesteuertes Goto verwandelt, ist er nicht so schnell wie das einfache Überprüfen auf Null.

Mark Bessey
quelle
3
Keine vorzeitige Optimierung! Wenn Sie mehr als nur einige wenige Fälle haben und diese switchkompatibel sind, ist die switchAussage im Allgemeinen besser (besser lesbar, manchmal schneller). Wenn Sie wissen, dass ein Fall viel wahrscheinlicher ist, können Sie ihn herausziehen, um ein if- else- switchKonstrukt zu bilden, und wenn er messbar schneller ist , lassen Sie ihn in. (Wiederholen Sie ihn, falls erforderlich.) IMO, die immer noch einigermaßen lesbar ist. Wenn das switchdegeneriert und zu klein wird, erledigt ein Regex-Ersatz den größten Teil der Arbeit, um es in eine else ifKette umzuwandeln.
niemand
6
Die ursprüngliche Frage (vor drei Jahren!) Fragte nur nach Vor- und Nachteilen zwischen if / else und switch. Dies ist ein Beispiel. Ich persönlich habe gesehen, dass diese Art der Optimierung einen signifikanten Unterschied in der Laufzeit einer Routine bewirkt.
Mark Bessey
7

oft sieht es besser aus - dh es ist leichter zu verstehen, was los ist. Angesichts der Tatsache, dass der Leistungsvorteil bestenfalls äußerst gering ist, ist die Ansicht des Codes der wichtigste Unterschied.

Wenn das if / else besser aussieht, verwenden Sie es, andernfalls verwenden Sie eine switch-Anweisung.

gbjbaanb
quelle
4

Nebenthema, aber ich mache mir oft Sorgen (und sehe öfter) if/ elseundswitch Aussage wird bei zu vielen Fällen viel zu groß. Diese beeinträchtigen häufig die Wartbarkeit.

Häufige Schuldige sind:

  1. Zu viel innerhalb mehrerer if-Anweisungen tun
  2. Mehr Fallaussagen als menschlich möglich zu analysieren
  3. Zu viele Bedingungen in der if-Bewertung, um zu wissen, wonach gesucht wird

Reparieren:

  1. Auszug zum Methoden-Refactoring.
  2. Verwenden Sie ein Wörterbuch mit Methodenzeigern anstelle eines Falls oder einen IoC für zusätzliche Konfigurierbarkeit. Methodenfabriken können ebenfalls hilfreich sein.
  3. Extrahieren Sie die Bedingungen nach ihrer eigenen Methode
Chris Brandsma
quelle
4

Gemäß diesem Link entspricht der Vergleich von IF und Switch des Iterationstests mit switch und if-Anweisung 1.000.000.000 Iterationen. Die Zeit, die Switch- Anweisung = 43,0 s und If-Anweisung = 48,0 s benötigt

Das sind buchstäblich 20833333 Iterationen pro Sekunde. Sollten wir uns wirklich mehr konzentrieren müssen ?

PS: Nur um den Leistungsunterschied für eine kleine Liste von Bedingungen zu kennen.

Bretfort
quelle
Das nagelt es für mich.
Greg Gum
3

Wenn Sie nur die if- oder else-Anweisung verwenden, verwendet die Basislösung den Vergleich? Operator

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

Sie können die Routine oder in einem Schalter ausführen

switch(typeCode)
{
   case TypeCode:Int32:
   case TypeCode.Int64:
     //dosomething here
     break;
   default: return;
}
Robert W.
quelle
2

Dies beantwortet Ihre Frage nicht wirklich, aber da es kaum Unterschiede zwischen den kompilierten Versionen gibt, möchte ich Sie dringend bitten, Ihren Code so zu schreiben, dass Ihre Absichten am besten beschrieben werden. Es besteht nicht nur eine bessere Chance, dass der Compiler das tut, was Sie erwarten, sondern es erleichtert auch anderen, Ihren Code zu pflegen.

Wenn Sie beabsichtigen, Ihr Programm basierend auf dem Wert einer Variablen / eines Attributs zu verzweigen, repräsentiert eine switch-Anweisung diese Absicht am besten.

Wenn Sie beabsichtigen, Ihr Programm basierend auf verschiedenen Variablen / Attributen / Bedingungen zu verzweigen, repräsentiert eine if / else if-Kette diese Absicht am besten.

Ich gebe zu, dass Cody Recht hat, wenn Leute den Befehl break vergessen, aber fast genauso häufig sehe ich Leute, die komplizierte Aktionen ausführen, wenn Blöcke, bei denen sie das {} falsch verstehen, Zeilen, die in der bedingten Anweisung enthalten sein sollten, nicht. Dies ist einer der Gründe, warum ich immer {} in meine if-Anweisungen einbinde, auch wenn eine Zeile darin enthalten ist. Es ist nicht nur einfacher zu lesen, sondern wenn ich eine weitere Zeile in die Bedingung einfügen muss, kann ich nicht vergessen, sie hinzuzufügen.

dj_segfault
quelle
2

Zinsfrage. Dies kam vor ein paar Wochen bei der Arbeit und wir fanden eine Antwort, indem wir ein Beispiel-Snippet schrieben und es in .NET Reflector betrachteten (Reflektor ist fantastisch !! ich liebe es).

Folgendes haben wir entdeckt: Eine gültige switch-Anweisung für etwas anderes als eine Zeichenfolge wird als switch-Anweisung in IL kompiliert. Wenn es sich jedoch um eine Zeichenfolge handelt, wird sie in IL als if / else if / else umgeschrieben. In unserem Fall wollten wir wissen, wie switch-Anweisungen Zeichenfolgen vergleichen, z. B. zwischen Groß- und Kleinschreibung unterscheiden usw. Der Reflektor gab uns schnell eine Antwort. Das war nützlich zu wissen.

Wenn Sie auf Zeichenfolgen vergleichen , um zu tun case-sensitive wollen , dann Sie könnte eine switch - Anweisung verwenden , da es schneller ist als ein String.Compare in einer if / else durchführen. (Bearbeiten: Lesen Was ist schneller, Zeichenfolge einschalten oder Typ einschalten? Für einige tatsächliche Leistungstests.) Wenn Sie jedoch die Groß- und Kleinschreibung nicht berücksichtigen möchten , ist es besser, ein if / else zu verwenden, da der resultierende Code nicht hübsch ist.

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

Die beste Faustregel ist, switch-Anweisungen zu verwenden, wenn dies (ernsthaft) sinnvoll ist, z.

  • Es verbessert die Lesbarkeit Ihres Codes
  • Sie vergleichen einen Wertebereich (float, int) oder eine Aufzählung

Wenn Sie den Wert bearbeiten müssen, um ihn in die switch-Anweisung einzuspeisen (erstellen Sie eine temporäre Variable, gegen die umgeschaltet werden soll), sollten Sie wahrscheinlich eine if / else-Steueranweisung verwenden.

Ein Update:

Es ist tatsächlich besser, den String in Großbuchstaben umzuwandeln (z. B. ToUpper()), da es anscheinend weitere Optimierungen gibt, die der Just-in-Time-Compiler im Vergleich zum ausführen kann ToLower(). Es ist eine Mikrooptimierung, aber in einer engen Schleife könnte es nützlich sein.


Eine kleine Randnotiz:

Versuchen Sie Folgendes, um die Lesbarkeit von switch-Anweisungen zu verbessern:

  • Stellen Sie den wahrscheinlichsten Zweig an die erste Stelle, dh den am häufigsten aufgerufenen
  • Wenn sie alle wahrscheinlich auftreten, listen Sie sie in alphabetischer Reihenfolge auf, damit Sie sie leichter finden können.
  • Verwenden Sie niemals den Standard-Catch-All für die letzte verbleibende Bedingung. Dies ist faul und führt später im Leben des Codes zu Problemen.
  • Verwenden Sie das Standard-Catch-All, um eine unbekannte Bedingung zu bestätigen, obwohl es höchst unwahrscheinlich ist, dass sie jemals auftreten wird. Dafür sind Behauptungen gut.
Dennis
quelle
In vielen Fällen ist die Verwendung von ToLower () die richtige Lösung, insbesondere wenn viele Fälle vorliegen und die Hash-Tabelle generiert wird.
Blaisorblade
"Wenn Sie den Wert bearbeiten müssen, um ihn in die switch-Anweisung einzuspeisen (erstellen Sie eine temporäre Variable, gegen die umgeschaltet werden soll), sollten Sie wahrscheinlich eine if / else-Steueranweisung verwenden." - Guter Rat, danke.
Sneakyness
2

Die switch-Anweisung ist definitiv die schnellere als eine if else if. Es gibt Speedtests, die von BlackWasp bereitgestellt wurden

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

--Hör zu

Hängt aber stark von den Möglichkeiten ab, die Sie zu berücksichtigen versuchen, aber ich versuche, wann immer möglich eine switch-Anweisung zu verwenden.

Schlacke
quelle
1

Ich denke, nicht nur C #, sondern alle C-basierten Sprachen: Da ein Schalter auf Konstanten beschränkt ist, ist es möglich, mithilfe einer "Sprungtabelle" sehr effizienten Code zu generieren. Der C-Fall ist wirklich ein gutes altes FORTRAN-berechnetes GOTO, aber der C # -Fall wird immer noch gegen eine Konstante getestet.

Es ist nicht der Fall, dass der Optimierer denselben Code erstellen kann. Betrachten Sie z.

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

Da es sich um zusammengesetzte Boolesche Werte handelt, muss der generierte Code einen Wert und einen Kurzschluss berechnen. Betrachten Sie nun das Äquivalent

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

Dies kann in kompiliert werden

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

weil Sie dem Compiler implizit mitteilen, dass er die OR- und Gleichheitstests nicht berechnen muss.

Charlie Martin
quelle
Es gibt keinen Grund, warum ein guter Optimierer den ersten Code nicht verarbeiten kann, solange der Optimierer implementiert ist. "Der Compiler kann nicht optimieren" hängt nur von semantischen Unterschieden ab, die nur der Mensch in Einklang bringen kann (dh wenn f () aufgerufen wird, weiß er nicht, dass f () immer 0 oder 1 zurückgibt).
Blaisorblade
0

Mein CS-Professor hat Ihnen vorgeschlagen, die Anweisungen nicht zu wechseln, da die Leute so oft die Pause vergessen oder sie falsch verwenden. Ich kann mich nicht genau erinnern, was er gesagt hat, aber etwas in der Richtung, dass das Betrachten einer wegweisenden Codebasis, die Beispiele für die switch-Anweisung (vor Jahren) zeigte, auch eine Menge Fehler enthielt.


quelle
Nicht wirklich ein Problem in C #. Siehe: stackoverflow.com/questions/174155/… ... und lesen Sie auch stackoverflow.com/questions/188461/…, um zu diskutieren, warum das Leben in Angst möglicherweise nicht die beste Politik ist ...
Shog9
0

Mir ist gerade aufgefallen, dass Sie if / else- und switch-Anweisungen kombinieren können! Sehr nützlich, wenn Sie die Voraussetzungen überprüfen müssen.

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;
}
Sogar Mien
quelle
3
Ich weiß, dass dies alt ist, aber ich denke, dass Sie technisch nichts "kombinieren". Jedes Mal, wenn Sie ein "else" ohne geschweifte Klammern haben, wird die nächste Anweisung ausgeführt. Diese Anweisung kann eine einzeilige Anweisung sein, die normalerweise in der nächsten Zeile eingerückt angezeigt wird, oder zusammengesetzte Anweisungen, wie dies bei if, switch, using, lock usw. der Fall ist. Mit anderen Worten, Sie können "else if", "haben. else switch "," else using "usw. Trotzdem gefällt mir, wie es aussieht und fast absichtlich aussieht. (Haftungsausschluss: Ich habe nicht alle diese versucht, so kann ich falsch sein!)
Nelson Rothermel
Nelson, du bist zu 100% richtig. Ich habe herausgefunden, warum dies passiert, nachdem ich diese Antwort gepostet habe.
Sogar Mien
0

Ich denke, Switch ist schneller als wenn Bedingungen wie sehen, ob es ein Programm gibt wie:

Schreiben Sie ein Programm, um eine beliebige Zahl (zwischen 1 - 99) einzugeben, und überprüfen Sie, in welchem ​​Steckplatz a) 1 - 9, dann Steckplatz eins b) 11 - 19, dann Steckplatz zwei c) 21-29, dann Steckplatz drei und so weiter bis 89- 99

Dann ein, wenn Sie viele Bedingungen erfüllen müssen, aber Son Switch Case müssen Sie nur eingeben

Schalter (Nr. / 10)

und in Fall 0 = 1-9, Fall 1 = 11-19 und so weiter

es wird so einfach sein

Es gibt noch viele weitere Beispiele!

Gemeinschaft
quelle
0

Eine switch-Anweisung ist im Grunde ein Vergleich für Gleichheit. Tastaturereignisse haben einen großen Vorteil gegenüber switch-Anweisungen, wenn sie einfach zu schreibenden und zu lesenden Code haben, und eine if elseif-Anweisung, bei der eine {Klammer} fehlt, kann ebenfalls problematisch werden.

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

Eine if elseif-Anweisung eignet sich für mehr als eine Lösung, wenn (theAmountOfApples ist größer als 5 && theAmountOfApples ist kleiner als 10) Ihre Äpfel speichern, wenn if (theAmountOfApples größer als 10 || theAmountOfApples == 100) Ihre Äpfel verkauft. Ich schreibe nicht c # oder c ++, aber ich habe es gelernt, bevor ich Java gelernt habe, und sie sind enge Sprachen.

Geen
quelle
0

Ein möglicher Nachteil von switch-Anweisungen ist das Fehlen mehrerer Bedingungen. Sie können mehrere Bedingungen für die if (else), aber nicht mehrere case-Anweisungen mit unterschiedlichen Bedingungen in einem Switch haben.

Switch-Anweisungen eignen sich nicht für logische Operationen, die über den Rahmen einfacher boolescher Gleichungen / Ausdrücke hinausgehen. Für diese booleschen Gleichungen / Ausdrücke ist es hervorragend geeignet, jedoch nicht für andere logische Operationen.

Sie haben viel mehr Freiheit mit der in If-Anweisungen verfügbaren Logik, aber die Lesbarkeit kann leiden, wenn die If-Anweisung unhandlich wird oder schlecht behandelt wird.

Beide haben dort Platz, abhängig vom Kontext, mit dem Sie konfrontiert sind.

Neil Meyer
quelle