14.1. Pattern Matching#

Pattern matching lets you test a value’s shape or type and branch accordingly. C# has evolved this from simple is checks to expressive switch expressions.

14.1.1. The is Operator#

is tests type and, if it matches, assigns the value to a new variable in one step.

object val = 42;

if (val is int n)
    Console.WriteLine($"It's an int: {n * 2}");  // It's an int: 84

object name = "Alice";
if (name is string s && s.Length > 3)
    Console.WriteLine($"Long name: {s}");  // Long name: Alice

14.1.2. Switch Expression#

The modern switch expression is concise — each arm is pattern => result.

static string Classify(int n) => n switch
{
    < 0  => "negative",
    0    => "zero",
    < 10 => "small positive",
    _    => "large positive"   // _ is the discard (default)
};

Console.WriteLine(Classify(-5));  // negative
Console.WriteLine(Classify(0));   // zero
Console.WriteLine(Classify(7));   // small positive
Console.WriteLine(Classify(42));  // large positive

14.1.3. Type Patterns#

Switch on the runtime type of an object — useful in OOP hierarchies.

static string Describe(object obj) => obj switch
{
    int i    => $"int: {i}",
    double d => $"double: {d:F2}",
    string s => $"string of length {s.Length}",
    null     => "null",
    _        => "something else"
};

Console.WriteLine(Describe(42));       // int: 42
Console.WriteLine(Describe(3.14));     // double: 3.14
Console.WriteLine(Describe("hello")); // string of length 5
Console.WriteLine(Describe(null));     // null

14.1.4. When Guards#

Add a when clause to a pattern arm for extra conditions.

static string Grade(int score) => score switch
{
    >= 90 => "A",
    >= 80 => "B",
    >= 70 => "C",
    >= 60 => "D",
    _     => "F"
};

Console.WriteLine(Grade(95));  // A
Console.WriteLine(Grade(83));  // B
Console.WriteLine(Grade(55));  // F

14.1.5. Tuple Patterns#

Match against multiple values at once by switching on a tuple.

static string RPS(string a, string b) => (a, b) switch
{
    ("Rock",     "Scissors") => "Player 1 wins",
    ("Scissors", "Paper")    => "Player 1 wins",
    ("Paper",    "Rock")     => "Player 1 wins",
    var (x, y) when x == y   => "Draw",
    _                        => "Player 2 wins"
};

Console.WriteLine(RPS("Rock", "Scissors"));  // Player 1 wins
Console.WriteLine(RPS("Rock", "Rock"));      // Draw
Console.WriteLine(RPS("Rock", "Paper"));     // Player 2 wins

14.1.6. Practice#

  1. Write string Season(int month) using a switch expression that returns "Spring", "Summer", "Fall", or "Winter".

  2. Write string HttpStatus(int code) that returns a description for 200, 404, 500, and a default "Unknown".

  3. Write a switch expression that classifies a char as 'vowel', 'digit', or 'other'.

Footnotes