C# Switch Expression Explained: A Practical Guide from Tim Corey
In the world of C# development, writing clean and maintainable code is a key objective. One modern C# feature that aids in achieving this is the switch expression—a compact and powerful alternative to the traditional switch statement. While often overlooked, switch expressions simplify complex branching logic, especially when dealing with relational patterns, pattern matching, and constant patterns.
To better understand how this feature works and how it compares to traditional approaches, we’ll walk through a helpful video by Tim Corey. Throughout his video on "Switch Expressions In C#", Tim breaks down real-world usage of switch expressions in C#, demonstrating how to write better code with fewer lines.
Let’s dive into Tim’s practical explanation, which starts with a grading example and builds toward more advanced scenarios using interfaces, type patterns, and object evaluation.
Traditional If-Else vs. Switch Expression
Tim begins with a console application where an int variable named numberGrade holds a test score like 85. The goal is to convert this numeric input value into a corresponding letter grade, such as 'B'. In most cases, developers would use a series of if-else statements or a switch statement, like this:
if (numberGrade >= 90)
letterGrade = "A";
else if (numberGrade >= 80)
letterGrade = "B";
// ...and so onif (numberGrade >= 90)
letterGrade = "A";
else if (numberGrade >= 80)
letterGrade = "B";
// ...and so onWhile this works, it's verbose. C# switch expressions, on the other hand, offer a cleaner syntax.
Writing a Switch Expression for Grading
To demonstrate a switch expression, Tim rewrites the above logic using the following code:
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"
};Here, the switch keyword is used in a new context—as an expression, not a statement. This means it evaluates to a value directly and can be assigned to a variable (like letterGrade).
This form supports relational patterns (e.g., >= 90) and uses the discard pattern (_) to handle the default case, which is equivalent to the final else.
Tim notes that the compiler determines the match at runtime, checking each condition top-down and choosing the first pattern that fits the input.
Simplifying Code with Expressions
In Tim’s words, this new syntax “replaces a whole lot of code.” Instead of repeating conditions with else if, the switch expression handles everything in a clear, concise structure. This simplifies control flow, improves readability, and reduces redundancy in your logic.
He emphasizes that this structure is especially useful when mapping input values to specific outputs—like grading, status messages, or data transformation.
Using Pattern Matching with Object Types
To explore type patterns and pattern matching, Tim introduces a scenario involving an IAnimal interface. He defines three classes—Dog, Cat, and Cow—each implementing the interface. This allows him to create a list of animals, each with different properties.
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;He populates a list with various animal instances and demonstrates how to use type pattern matching to identify the object type and extract the data.
Switch Expression with Pattern Matching
Tim shows how the following code using if statements:
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";Can be replaced by a much more compact and readable switch expression:
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"
};This expression checks the type of the object and applies the correct output based on the matched pattern. If no match is found, it falls back to a default result using the discard _.
This feature enhances functionality without sacrificing clarity. The runtime behavior remains predictable and readable.
Optional Guards with the when Keyword
Although not demonstrated in Tim’s example, it’s important to note that switch expressions can be extended with the when keyword to apply an optional boolean condition:
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"
};Here, the when clause allows for custom evaluation of the argument, using more complex boolean expressions.
Best Practices and Final Thoughts
Tim emphasizes a critical concept: while switch expressions make your code more compact, compact doesn't always mean better. Sometimes, especially with complicated logic or unclear inputs, a traditional switch statement or if block may be more appropriate.
You don’t have to use a switch expression in every case—use the right tool for the job. This is not about joining the "switch cult," as Tim jokes. It’s about writing maintainable and understandable code in your system.
Summary: Adding Switch Expressions to Your Developer Toolbox
C# switch expressions offer a modern, clean way to evaluate and return values based on input patterns, using a combination of constant, relational, and type patterns. They’re ideal when you want to simplify logic, reduce boilerplate, and improve readability.
From grading integers to identifying animal objects, the following examples in Tim Corey’s video highlight their practical uses. Whether you're building a function to calculate results, handling user input, or working with null and undefined cases, switch expressions can help save time, reduce errors, and make your codebase easier to manage.
As Tim says, “They are a really helpful tool to have in your toolbox to make your code simpler and cleaner—and yet still be as understandable, if not more.”
If you’re looking to improve your C# code quality and keep up with .NET Core innovations, don’t skip over switch expressions. Try them out, experiment in your Visual Studio projects, and see how much cleaner your logic can become.
