hamsterbyte

Advanced Pattern Matching in Modern C#

Pattern matching has evolved significantly in recent C# versions, becoming one of the language’s most expressive features. Let’s explore the powerful patterns available today.

Type Patterns

The most basic form checks types and declares variables:

object obj = "Hello";
if (obj is string s)
{
    Console.WriteLine(s.ToUpper());
}

Property Patterns

Match on object properties directly:

public decimal GetDiscount(Order order) => order switch
{
    { Total: > 1000, IsPremium: true } => 0.20m,
    { Total: > 500 } => 0.10m,
    { IsFirstOrder: true } => 0.15m,
    _ => 0m
};

Positional Patterns

Deconstruct and match in one step:

public string Classify(Point point) => point switch
{
    (0, 0) => "Origin",
    (var x, 0) => $"On X-axis at {x}",
    (0, var y) => $"On Y-axis at {y}",
    var (x, y) => $"Point at ({x}, {y})"
};

Relational Patterns

Use comparison operators in patterns:

public string GetTemperatureDescription(int temp) => temp switch
{
    < 0 => "Freezing",
    >= 0 and < 15 => "Cold",
    >= 15 and < 25 => "Moderate",
    >= 25 => "Hot"
};

List Patterns (C# 11)

Match array and list contents:

public bool IsValidSequence(int[] numbers) => numbers switch
{
    [] => false,
    [var single] => single > 0,
    [var first, .. var rest] => first > 0 && IsValidSequence(rest),
};

Pattern matching makes your code more declarative and easier to understand. Embrace it for cleaner conditional logic!

Tags: