🎯 Pattern Matching = Cleaner Code
Complex conditionals are hard to read. Pattern matching makes code more expressive and maintainable.
📝 Pattern Matching Basics
// Type Patterns
public void ProcessShape(object shape)
{
if (shape is Circle circle)
{
Console.WriteLine($"Circle with radius {circle.Radius}");
}
else if (shape is Rectangle rect)
{
Console.WriteLine($"Rectangle {rect.Width}x{rect.Height}");
}
else if (shape is Triangle tri)
{
Console.WriteLine($"Triangle with sides {tri.SideA}, {tri.SideB}, {tri.SideC}");
}
}
// Switch Expression (C# 8+)
public string GetShapeInfo(object shape) => shape switch
{
Circle { Radius: > 10 } => "Large circle",
Circle { Radius: > 5 } => "Medium circle",
Circle { Radius: <= 5 } => "Small circle",
Rectangle { Width: var w, Height: var h } when w == h => $"Square ({w}x{h})",
Rectangle { Width: var w, Height: var h } => $"Rectangle ({w}x{h})",
Triangle { SideA: var a, SideB: var b, SideC: var c } => $"Triangle ({a},{b},{c})",
null => "Null object",
_ => "Unknown shape"
};
// Property Patterns
public bool IsValidUser(User user) => user is
{
Age: > 18,
Email: not null,
Status: UserStatus.Active
};
🎯 Advanced Pattern Matching
// Tuple Patterns
public string EvaluateState(bool isActive, bool isVerified) => (isActive, isVerified) switch
{
(true, true) => "Fully active",
(true, false) => "Active but unverified",
(false, true) => "Verified but inactive",
(false, false) => "Inactive and unverified"
};
// Relational Patterns (C# 9+)
public string GetTemperatureCategory(int temperature) => temperature switch
{
< 0 => "Freezing",
< 10 => "Cold",
< 20 => "Cool",
< 30 => "Warm",
< 40 => "Hot",
>= 40 => "Very hot"
};
// Logical Patterns
public string GetStudentGrade(int score) => score switch
{
>= 90 and <= 100 => "A",
>= 80 and < 90 => "B",
>= 70 and < 80 => "C",
>= 60 and < 70 => "D",
< 60 => "F",
_ => "Invalid score"
};
// Positional Patterns
public record Point(int X, int Y);
public string DescribePoint(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, var y) when x == y => $"On diagonal at ({x},{y})",
(var x, var y) => $"At ({x},{y})"
};
// List Patterns (C# 11+)
public string DescribeNumbers(int[] numbers) => numbers switch
{
[] => "Empty array",
[1] => "Single item: 1",
[1, 2] => "Exactly [1, 2]",
[1, ..] => "Starts with 1",
[_, _, 3] => "Ends with 3",
[var first, var second, ..] => $"First two: {first}, {second}",
_ => "Other array"
};
💡 Pattern Matching Tips
- Use switch expressions for concise logic
- Combine with property patterns
- Use when clauses for complex conditions
- Handle all cases in switch expressions
- Use patterns for validation
Pattern matching makes C# code more declarative and readable. It reduces boilerplate and eliminates common bugs.
