Introduction
Pattern matching is a powerful feature introduced in C# 7 that provides concise syntax for conditional checks in data structures. This blog post explores advanced pattern matching techniques and demonstrates real-world applications. We’ll begin with an understanding of pattern matching basics and then delve into advanced techniques.
Understanding Pattern Matching Basics
Before diving into advanced techniques, let’s review the fundamentals of pattern matching in C#:
-
Switch Expressions: C# 7.0 introduced switch expressions, a powerful replacement for the traditional switch statement that allows for pattern matching in a more concise manner.
-
Pattern Matching with
is
: Theis
keyword is used to check if an object matches a specific pattern. -
Tuple Patterns: Tuple patterns enable matching against multiple elements simultaneously.
Advanced Techniques
1. Recursive Patterns
Recursive patterns allow you to deconstruct objects within patterns, making them particularly valuable when working with hierarchical data structures.
public class Node
{
public int Value { get; set; }
public Node Next { get; set; }
}
var node = new Node { Value = 42, Next = new Node { Value = 24 } };
if (node is { Value: 42, Next: { Value: 24 } })
{
Console.WriteLine("Pattern matched successfully!");
}
2. Positional Patterns
Positional patterns enable matching based on the position of elements in collections, tuples, or user-defined types.
public class Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
}
var point = new Point(3, 4);
if (point is (3, 4))
{
Console.WriteLine("Pattern matched successfully!");
}
Real-world Application
Fizz Buzz
Pattern matching simplifies common algorithms like FizzBuzz. Let’s explore how pattern matching can be applied to FizzBuzz:
public void FizzBuzzUsingPatternMatch(int i)
{
var result = (i % 3, i % 5) switch
{
(0, 0) => "fizzbuzz",
(0, _) => "fizz",
(_, 0) => "buzz",
_ => i.ToString()
};
Console.WriteLine(result);
}
Let’s now translate the switch statement to a pattern matching statement. Here’s the code: The syntax I’m using is pattern matching. Let’s take a closer look at each line
- If all conditions are satisfied, the outcome is (0,0).
- (0,_) if the first condition is met (ignore second one)
- (_,0) If the second condition is met
- _ if none of them are matching
Handling HTTP Responses
Now, let’s apply pattern matching to a real-world scenario—handling HTTP responses. This example demonstrates how pattern matching can simplify complex decision logic in practical situations:
var response = GetHttpResponse(); // This method retrieves an HttpResponse object
switch (response)
{
case { StatusCode: 200, IsSuccess: true, Content: var content }:
Console.WriteLine($"Success! Content: {content}");
break;
case { StatusCode: >= 400, StatusCode: < 500, Content: var content }:
Console.WriteLine($"Client error! Content: {content}");
break;
case { StatusCode: >= 500 }:
Console.WriteLine("Server error!");
break;
default:
Console.WriteLine("Unknown response!");
break;
}
Conclusion
C# pattern matching is a powerful feature that significantly enhances code readability and maintainability. By mastering advanced techniques like recursive and positional patterns and applying them to real-world scenarios, you can elevate your C# programming skills to new heights.
Pattern matching simplifies complex conditional logic and fosters expressive and precise code, making it a valuable addition to your developer toolkit.