C# Switch Expression Erklärt: Ein praktischer Leitfaden von Tim Corey
In der Welt der C#-Entwicklung ist das Schreiben von sauberem und wartbarem Code ein wichtiges Ziel. Ein modernes C#-Feature, das dabei hilft, dies zu erreichen, ist der Switch-Ausdruck - eine kompakte und leistungsstarke Alternative zur traditionellen Switch-Anweisung. Obwohl sie oft übersehen werden, vereinfachen Switch-Ausdrücke komplexe Verzweigungslogik, insbesondere beim Umgang mit relationalen Mustern, Musterabgleich und konstanten Mustern.
Um besser zu verstehen, wie diese Funktion funktioniert und wie sie sich von herkömmlichen Ansätzen unterscheidet, sehen wir uns ein hilfreiches Video von Tim Corey an. In seinem Video über "Switch-Ausdrücke in C#" erläutert Tim die praktische Verwendung von Switch-Ausdrücken in C# und zeigt, wie man mit weniger Zeilen besseren Code schreiben kann.
Tauchen wir ein in Tims praktische Erklärung, die mit einem Einstufungsbeispiel beginnt und auf fortgeschrittenere Szenarien mit Schnittstellen, Typmustern und Objektevaluierung aufbaut.
Traditioneller If-Else-Ausdruck vs. Switch-Ausdruck
Tim beginnt mit einer Konsolenanwendung, in der eine int-Variable mit dem Namen numberGrade eine Testpunktzahl wie 85 enthält. Ziel ist es, diesen numerischen Eingabewert in eine entsprechende Buchstabennote zu konvertieren, z. B. "B". In den meisten Fällen verwenden die Entwickler eine Reihe von if-else-Anweisungen oder eine switch-Anweisung, etwa so:
if (numberGrade >= 90)
letterGrade = "A";
else if (numberGrade >= 80)
letterGrade = "B";
// ...and so on
if (numberGrade >= 90)
letterGrade = "A";
else if (numberGrade >= 80)
letterGrade = "B";
// ...and so on
Das funktioniert zwar, ist aber sehr langatmig. C#-Switch-Ausdrücke hingegen bieten eine sauberere Syntax.
Schreiben eines Switch-Ausdrucks für die Benotung
Um einen Switch-Ausdruck zu demonstrieren, schreibt Tim die obige Logik mit dem folgenden Code um:
string letterGrade = numberGrade switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F"
};
string letterGrade = numberGrade switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F"
};
Hier wird das Schlüsselwort switch in einem neuen Kontext verwendet - als Ausdruck, nicht als Anweisung. Das bedeutet, dass er direkt zu einem Wert ausgewertet wird und einer Variablen (wie letterGrade) zugewiesen werden kann.
Dieses Formular unterstützt relationale Muster (z. B. >= 90) und verwendet das Verwerfungsmuster (_), um den Standardfall zu behandeln, der dem letzten else entspricht.
Tim merkt an, dass der Compiler die Übereinstimmung zur Laufzeit bestimmt, indem er jede Bedingung von oben nach unten überprüft und das erste Muster auswählt, das auf die Eingabe passt.
Vereinfachung von Code mit Ausdrücken
Nach Tims Worten ersetzt diese neue Syntax "eine ganze Menge Code" Anstatt Bedingungen mit else if zu wiederholen, behandelt der switch-Ausdruck alles in einer klaren, prägnanten Struktur. Dies vereinfacht den Kontrollfluss, verbessert die Lesbarkeit und reduziert Redundanzen in Ihrer Logik.
Er betont, dass diese Struktur besonders nützlich ist, wenn es darum geht, Eingabewerte auf bestimmte Ausgaben abzubilden, z. B. Abstufungen, Statusmeldungen oder Datentransformationen.
Verwendung von Pattern Matching mit Objekttypen
Um Typmuster und Mustervergleiche zu erforschen, stellt Tim ein Szenario mit einer IAnimal-Schnittstelle vor. Er definiert drei Klassen - Hund, Katze und Kuh -, die jeweils die Schnittstelle implementieren. So kann er eine Liste von Tieren erstellen, die jeweils unterschiedliche Eigenschaften haben.
interface IAnimal { }
record Dog(string Name) : IAnimal;
record Cat(string Title, string Name) : IAnimal;
record Cow(string Breed) : IAnimal;
interface IAnimal { }
record Dog(string Name) : IAnimal;
record Cat(string Title, string Name) : IAnimal;
record Cow(string Breed) : IAnimal;
Er füllt eine Liste mit verschiedenen Tierinstanzen auf und demonstriert, wie der Typ-Musterabgleich verwendet werden kann, um den Objekttyp zu identifizieren und die Daten zu extrahieren.
Switch Expression mit Pattern Matching
Tim zeigt, wie der folgende Code mit if-Anweisungen funktioniert:
if (a is Dog d)
message = $"Dog: {d.Name}";
else if (a is Cat c)
message = $"Cat: {c.Title} {c.Name}";
else if (a is Cow co)
message = $"Cow: {co.Breed}";
else
message = "Unknown animal";
if (a is Dog d)
message = $"Dog: {d.Name}";
else if (a is Cat c)
message = $"Cat: {c.Title} {c.Name}";
else if (a is Cow co)
message = $"Cow: {co.Breed}";
else
message = "Unknown animal";
Kann durch einen viel kompakteren und lesbareren Switch-Ausdruck ersetzt werden:
string message = a switch
{
Dog d => $"Dog: {d.Name}",
Cat c => $"Cat: {c.Title} {c.Name}",
Cow co => $"Cow: {co.Breed}",
_ => "Unknown animal"
};
string message = a switch
{
Dog d => $"Dog: {d.Name}",
Cat c => $"Cat: {c.Title} {c.Name}",
Cow co => $"Cow: {co.Breed}",
_ => "Unknown animal"
};
Dieser Ausdruck prüft den Typ des Objekts und wendet die richtige Ausgabe auf der Grundlage des übereinstimmenden Musters an. Wenn keine Übereinstimmung gefunden wird, wird mit der Funktion "Verwerfen" auf ein Standardergebnis zurückgegriffen.
Diese Funktion verbessert die Funktionalität, ohne die Klarheit zu beeinträchtigen. Das Laufzeitverhalten bleibt vorhersehbar und lesbar.
Optionale Schutzmaßnahmen mit dem Schlüsselwort when
Obwohl in Tims Beispiel nicht gezeigt, ist es wichtig zu wissen, dass switch-Ausdrücke mit dem when-Schlüsselwort erweitert werden können, um eine optionale boolesche Bedingung anzuwenden:
int score = 90;
string result = score switch
{
int s when s >= 90 && s <= 100 => "Excellent",
int s when s >= 75 => "Good",
_ => "Needs Improvement"
};
int score = 90;
string result = score switch
{
int s when s >= 90 && s <= 100 => "Excellent",
int s when s >= 75 => "Good",
_ => "Needs Improvement"
};
Hier ermöglicht die when-Klausel eine benutzerdefinierte Auswertung des Arguments unter Verwendung komplexerer boolescher Ausdrücke.
Best Practices und abschließende Überlegungen
Tim hebt ein wichtiges Konzept hervor: Switch-Ausdrücke machen Ihren Code zwar kompakter, aber kompakt bedeutet nicht immer besser. Manchmal, insbesondere bei komplizierter Logik oder unklaren Eingaben, kann eine herkömmliche switch-Anweisung oder ein if-Block besser geeignet sein.
Sie müssen nicht in jedem Fall einen Switch-Ausdruck verwenden - verwenden Sie das richtige Tool für die jeweilige Aufgabe. Es geht nicht darum, dem "Switch-Kult" beizutreten, wie Tim scherzt. Es geht um das Schreiben von wartbarem und verständlichem Code in Ihrem System.
Zusammenfassung: Hinzufügen von Switch-Ausdrücken zu Ihrer Entwickler-Toolbox
C#-Switch-Ausdrücke bieten eine moderne, saubere Möglichkeit, Werte auf der Grundlage von Eingabemustern zu bewerten und zurückzugeben, wobei eine Kombination aus Konstanten-, relationalen und Typmustern verwendet wird. Sie sind ideal, wenn Sie die Logik vereinfachen, Kauderwelsch reduzieren und die Lesbarkeit verbessern möchten.
Die folgenden Beispiele im Video von Tim Corey verdeutlichen die praktischen Einsatzmöglichkeiten, von der Einstufung ganzer Zahlen bis hin zur Identifizierung von tierischen Objekten. Ganz gleich, ob Sie eine Funktion zur Berechnung von Ergebnissen erstellen, Benutzereingaben verarbeiten oder mit Null- und undefinierten Fällen arbeiten, Switch-Ausdrücke können Ihnen helfen, Zeit zu sparen, Fehler zu reduzieren und Ihre Codebasis einfacher zu verwalten.
Tim sagt: "Sie sind ein wirklich hilfreiches Werkzeug, das man in seinem Werkzeugkasten hat, um seinen Code einfacher und sauberer zu machen - und trotzdem genauso verständlich, wenn nicht sogar noch besser."
Wenn Sie die Qualität Ihres C#-Codes verbessern und mit den Innovationen von .NET Core Schritt halten möchten, sollten Sie Switch Expressions nicht übergehen. Probieren Sie sie aus, experimentieren Sie in Ihren Visual Studio-Projekten und sehen Sie, wie viel sauberer Ihre Logik werden kann.
