The switch statement has been part of C# since day one.
But over time, it has evolved into a powerful tool for pattern matching .
In this article, we'll look at how the switch statement has changed and see why the modern switch is more useful.
The Traditional switch
The classic switch has been around since C# 1.0.
It only worked on constants (int, char, enums, strings).
Each case needed a break (or return).
Example
public string GetColor(Color c)
{
switch (c)
{
case Color.Red:
case Color.Blue:
case Color.Yellow:
return "Primary Colors";
default:
return "Other";
}
}
Modern switch with Pattern Matching
Starting with C# 7.0, the switch statement gained pattern matching. Later releases expanded it:
Type patterns, constant patterns, and when clauses.
Switch expressions + property/tuple patterns.
Relational (>, <, >=, <=) and logical (and, or, not) patterns.
Type patterns Example
object value = 42;
string result = value switch
{
int n => $"Integer: {n}",
string s => $"String: {s}",
null => "Null value",
_ => "Unknown type"
};
Relational Patterns
This switch expression is used to compare an expression result with a constant, as the following example shows:
int score = 85;
string grade = score switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "F"
};
In a relational pattern, we can use the relational operators <, >, <=, or >=.
Positional pattern
Can be used to deconstruct a result and match it values as the following example:
(int x, int y) point = (5, -3);
string position = point switch
{
(0, 0) => "Origin",
( > 0, > 0) => "Quadrant I",
( < 0, > 0) => "Quadrant II",
( < 0, < 0) => "Quadrant III",
( > 0, < 0) => "Quadrant IV",
_ => "On axis"
};
There still exists many other patterns present in the documentation, each can be served and used in a specific situation, more specific than the general cases we encounter.