DEV Community

Cover image for The Art of C# Pattern Matching
Hootan Hemmati
Hootan Hemmati

Posted on • Edited on

The Art of C# Pattern Matching

Pattern matching in C# is a powerful feature introduced in C# 7.0 and improved upon in later versions. It enables developers to perform concise and expressive checks on data structures, making it easier to work with complex types and perform conditional operations. Pattern matching is particularly helpful in the following situations:

Switch Statements

Pattern matching enhances switch statements, allowing developers to match cases based on complex patterns rather than just simple constant values. It enables the use of various patterns like type patterns, property patterns, tuple patterns, and more, making switch statements more versatile and readable.

Example:

public string GetVehicleType(object vehicle)
{
    switch (vehicle)
    {
        case Car _:
            return "Car";
        case Bike _:
            return "Bike";
        case Truck _:
            return "Truck";
        default:
            return "Unknown";
    }
}
Enter fullscreen mode Exit fullscreen mode

Type Patterns

Pattern matching can be used to check the type of an object and perform actions based on the type. It simplifies type checking and casting, eliminating the need for explicit type checks and conversions.

Example:

public void ProcessShape(Shape shape)
{
    if (shape is Circle circle)
    {
        // Do something with circle
    }
    else if (shape is Rectangle rectangle)
    {
        // Do something with rectangle
    }
    // More type patterns can be added here
}
Enter fullscreen mode Exit fullscreen mode

Property Patterns

Property patterns allow pattern matching based on the properties of an object. It is particularly useful when working with complex data structures or domain models.

Example:

public string GetWeatherMessage(WeatherInfo info)
{
    return info switch
    {
        { Temperature: < 0 } => "It's freezing outside!",
        { Temperature: >= 30, IsSunny: true } => "It's a hot and sunny day!",
        { IsRainy: true } => "Don't forget your umbrella!",
        _ => "Weather is moderate."
    };
}
Enter fullscreen mode Exit fullscreen mode

Tuple Patterns

Pattern matching with tuples simplifies working with tuples and deconstructing their elements in a more readable manner.

Example:

public string GetQuadrantName((int x, int y) point)
{
    return point switch
    {
        (0, 0) => "Origin",
        (var x, var y) when x > 0 && y > 0 => "Quadrant I",
        (var x, var y) when x < 0 && y > 0 => "Quadrant II",
        // More tuple patterns can be added here
        _ => "Other Quadrant"
    };
}
Enter fullscreen mode Exit fullscreen mode

Deconstruction

Pattern matching can be used in conjunction with deconstruction to extract values from complex objects easily.

Example:

var (firstName, lastName) = GetFullName("John Doe");
Enter fullscreen mode Exit fullscreen mode

Null Check and Nullable Patterns

Pattern matching can also simplify null checks and handle nullable types more effectively.

Example:

public string GetCountryName(Country? country)
{
    return country switch
    {
        { Name: string name } => name,
        null => "Unknown Country"
    };
}
Enter fullscreen mode Exit fullscreen mode

Summary:
Pattern matching in C# simplifies complex conditional checks, type handling, and deconstruction, making the code more expressive, concise, and readable. By enabling the use of various patterns, developers can write more robust code with fewer null reference exceptions and type-related issues. Pattern matching is a valuable addition to C#, allowing developers to work with complex data structures and types more efficiently.

Top comments (0)