The Art of C# Pattern Matching
Tags: beginners, csharp, dotnet, programming
Published: 2023-07-22 21:21:08

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:_

```c#
public string GetVehicleType(object vehicle)
{
    switch (vehicle)
    {
        case Car _:
            return "Car";
        case Bike _:
            return "Bike";
        case Truck _:
            return "Truck";
        default:
            return "Unknown";
    }
}
```

## 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:_

```c#
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
}
```

## 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:_

```c#
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."
    };
}
```

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

_Example:_

```c#
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"
    };
}
```

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

_Example:_

```c#
var (firstName, lastName) = GetFullName("John Doe");
```

## Null Check and Nullable Patterns
Pattern matching can also simplify null checks and handle nullable types more effectively.

_Example:_

```c#
public string GetCountryName(Country? country)
{
    return country switch
    {
        { Name: string name } => name,
        null => "Unknown Country"
    };
}
```
**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.