Menu

C# if else: else if-Ketten, Bedingungen und häufige Fehler

Wie if, else if und else in C# funktionieren: warum Bedingungen bool sein müssen, Tests mit &&, || und ! kombinieren, wann geschweifte Klammern zählen, Guard Clauses statt tiefer Verschachtelung und die Fehler mit = gegenüber == und dem verirrten Semikolon.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Eine if-Anweisung führt einen Codeblock nur aus, wenn eine Bedingung wahr ist. else if fügt weitere Tests hinzu, und else fängt alles ab, was die Tests nicht erfasst haben.

Ausgabe:

Order 120: shipping 0
Order 75.50: shipping 4.99
Order 20: shipping 9.99

Die Bedingungen werden von oben nach unten geprüft, und die erste wahre gewinnt. Eine Bestellung über 120 passt auf >= 100 und erreicht den Test >= 50 nie, deshalb steht die spezifischste Bedingung zuerst. else if ist kein eigenes Schlüsselwort: Es ist ein else, dessen Rumpf ein weiteres if ist, in C# gibt es also kein elseif oder elif.

Bedingungen müssen bool sein

C# behandelt eine Zahl, einen String oder ein Objekt nie als true oder false. Der Ausdruck in Klammern muss den Typ bool haben:

int count = 3;
if (count)          // error CS0029: Cannot implicitly convert type 'int' to 'bool'
if (count > 0)      // correct
if (name)           // error: a string is not a bool either
if (name != null)   // correct

Das beseitigt eine ganze Familie von Bugs aus C und JavaScript, wo 0, "" und null stillschweigend als false gelten. Der Preis ist, dass du den Vergleich jedes Mal ausschreibst, was die Absicht aber auch für den nächsten Leser sichtbar macht.

Bedingungen mit &&, || und ! kombinieren

&& (und), || (oder) und ! (nicht) kombinieren boolesche Tests. && und || werten kurzgeschlossen aus: Die rechte Seite läuft nur, wenn die linke die Antwort nicht schon entschieden hat.

Ausgabe:

maya: welcome
invalid or banned account
invalid or banned account
omar: age 9 rejected
invalid or banned account

Der Aufruf mit null ist dank der Kurzschlussauswertung sicher: Sobald username != null false ist, wird username.Length nie ausgewertet, also keine NullReferenceException. Dreh die Reihenfolge zu username.Length >= 3 && username != null um, und derselbe Aufruf stürzt ab.

&& bindet stärker als ||, also bedeutet a || b && c dasselbe wie a || (b && c). Setze Klammern, wann immer du beide mischst; der Compiler braucht sie nicht, die Leser schon. Die einfachen & und | funktionieren auch mit bool, werten aber immer beide Seiten aus. Nimm sie nur, wenn die rechte Seite einen Nebeneffekt hat, der passieren muss.

Geschweifte Klammern und die Regel der einen Anweisung

Klammern sind optional, wenn ein Zweig eine einzige Anweisung enthält. Ohne sie gehört nur die nächste Anweisung zum if, egal was die Einrückung sagt:

Ausgabe:

Reorder email sent
Stock: 12

„Reorder email sent“ wird ausgegeben, obwohl der Bestand in Ordnung ist: Das zweite WriteLine steht trotz Einrückung außerhalb des if. Eine einzeilige Absicherung wie if (x == null) return; ist ohne Klammern in Ordnung; alles, was eine zweite Zeile bekommen könnte, sollte sie haben.

Ein verwandter Bug ist ein Semikolon direkt nach der Bedingung. if (stock < 5); beendet das if mit einer leeren Anweisung, und der folgende Block läuft bedingungslos. Der Compiler markiert das mit Warnung CS0642, Possible mistaken empty statement, die du wie einen Fehler behandeln solltest.

= gegenüber == in einer Bedingung

= weist zu, == vergleicht. Bei den meisten Typen kompiliert ein versehentliches = nicht, weil das Ergebnis einer Zuweisung der zugewiesene Wert ist und ein int kein bool ist:

int score = 10;
if (score = 100) { }   // error CS0029: Cannot implicitly convert type 'int' to 'bool'

Bei einer bool-Variable ist die Zuweisung selbst ein bool, der Tippfehler kompiliert also:

Ausgabe:

Access granted
isAdmin is now True

Die Bedingung hat isAdmin überschrieben und dann den neuen Wert getestet. Der Compiler warnt (CS0665, assignment in a conditional expression is always constant), aber der Build gelingt trotzdem. Bei Bools lass den Vergleich ganz weg: if (isAdmin) und if (!isAdmin) lesen sich besser und lassen sich so nicht vertippen.

Verschachteltes if gegenüber Guard Clauses

Jede Verschachtelungsebene ist eine weitere Bedingung, die der Leser im Kopf behalten muss. Wenn jede Prüfung ungültige Eingaben abweist, kehre früh zurück, statt den Normalfall in allen Prüfungen zu verschachteln:

Ausgabe:

ordered 2 x keyboard
error: no product
error: quantity must be positive
error: insufficient balance

Die verschachtelte Version derselben Methode hätte drei Ebenen von if, mit der eigentlichen Arbeit im innersten Block und drei else-Zweigen, die sich unten auflösen. Mit Guard Clauses steht jede Regel neben ihrer Fehlermeldung, und die letzte Zeile ist der Normalfall. Dieselbe Idee funktioniert in Schleifen mit continue.

Variablen in der Bedingung deklarieren

Eine Bedingung kann eine Variable deklarieren, die innerhalb des if gültig ist. Die zwei üblichen Formen sind ein out var aus einer TryParse-Methode und das is-Typmuster:

Ausgabe:

42: positive number 42
abc: not a number
-7: number -7, not positive
string of length 5

TryParse gibt bei fehlerhafter Eingabe false zurück, statt zu werfen, und passt daher natürlich in ein if. Die Seite zur Typumwandlung behandelt die Parse-Methoden im Detail.

Wann etwas anderes besser passt

  • Einen von zwei Werten wählen: Der Bedingungsoperator condition ? a : b ist kürzer als ein if, das in beiden Zweigen zuweist.
  • Viele Zweige für einen Wert: Eine switch-Anweisung vergleicht einen Wert mit konstanten Fällen und ist leichter zu überblicken als zehn else if-Zeilen.
  • Einen Wert auf ein Ergebnis abbilden: Ein Lookup in einem Dictionary ersetzt eine lange Kette, wenn sich die Zweige nur in Daten unterscheiden.

Häufig gestellte Fragen

Wie schreibt man else if in C#?

Schreibe else if als zwei Wörter: if (a) { ... } else if (b) { ... } else { ... }. Die Bedingungen werden von oben nach unten geprüft, und nur der erste wahre Zweig läuft, setze also den spezifischsten Test an den Anfang. Ein Schlüsselwort elif oder elseif gibt es nicht.

Warum kann ich in C# nicht if (count) schreiben?

Eine Bedingung muss in C# vom Typ bool sein. Anders als in C und JavaScript wird ein int, ein String oder ein Objekt nie in true oder false umgewandelt, if (count) scheitert also mit CS0029, Cannot implicitly convert type 'int' to 'bool'. Schreibe den Test, den du meinst: if (count > 0) oder if (name != null).

Was ist der Unterschied zwischen && und & in einer if-Bedingung?

&& wertet kurzgeschlossen aus: Ist die linke Seite false, wird die rechte nie ausgewertet, und genau das macht s != null && s.Length > 0 sicher. & wertet bei zwei Bools jedes Mal beide Seiten aus. Dasselbe gilt für || und |. Nimm in Bedingungen && und ||, außer du brauchst den Nebeneffekt der rechten Seite.

Sind geschweifte Klammern in einer C#-if-Anweisung Pflicht?

Nein. Ohne Klammern steuert das if genau eine Anweisung. Eine zweite Zeile einzurücken fügt sie nicht zum Zweig hinzu, eine klassische Fehlerquelle, deshalb empfehlen die meisten Styleguides Klammern an jedem Zweig.

Kann ich in C# ein if else in einer Zeile schreiben?

Um einen Wert zu wählen, nimm den Bedingungsoperator: string label = score >= 50 ? "pass" : "fail";. Um Anweisungen auszuführen, ist if (x) DoA(); else DoB(); in einer Zeile erlaubt, aber schwerer zu lesen und zu erweitern als ein Block mit Klammern.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S