Pattern Matching in Csharp

Pattern matching is a powerful feature in C# that simplifies how data and conditions are handled. This allows you to view the object's size, quality, or value in a concise and readable format. This feature, introduced in C# 7.0 and enhanced in later versions, replaces complex conditional logic with cleaner and more transparent code. 

What is Pattern Matching?

Pattern matching allows you to directly evaluate the size, type, or value of objects within the expression, without the need for a complex conditional statement. It's similar to what you might find in functional programming languages, but C# provides syntax and builds it.

Instead of using multiple "if-else" or "switch" blocks to check types and values, pattern matching provides a cleaner and more efficient way of performing these checks. It is most commonly used with "is" expressions and "switch" expressions/statements.

Types of Pattern Matching

C# provides several types of pattern matching, including:

Type Pattern

Type patterns are the simplest form of pattern matching. It checks if a value is of a certain type and assigns it to a new variable.

Example

Here, In this example, the is operator checks the object type. If it matches string or int, the value is assigned to the variable s or i, and we can directly use it in the following block.

csharp
​​public void PrintType(object obj) { if (obj is string s) { Console.WriteLine($"The object is a string with value: {s}"); } else if (obj is int i) { Console.WriteLine($"The object is an integer with value: {i}"); } else { Console.WriteLine("Unknown object type."); } }

Constant Patterns

A constant pattern compares the input to a specific constant value, much like a traditional switch statement.

Example

Here, in this example, the switch expression is used to match the character grade to constant values. The corresponding result is returned if the grade matches any of the specified letters.

csharp
public string EvaluateGrade(char grade) { return grade switch { 'A' => "Excellent", 'B' => "Good", 'C' => "Average", 'D' => "Below Average", 'F' => "Fail", _ => "Invalid grade" }; }

Relational Patterns

The relational patterns allow you to compare values using relational operators, like <, >, <=, or >=.

Example

This example categorizes a person’s age based on relational comparisons. It uses relational operators within the switch expression, making the code compact and easier to understand.

csharp
public string CategorizeAge(int age) { return age switch { < 13 => "Child", >= 13 and < 18 => "Teenager", >= 18 and < 65 => "Adult", >= 65 => "Senior", _ => "Unknown age" }; }

Logical Patterns

The Logical patterns combine multiple patterns using logical operators like "and", "or", and "not".

Example

Here, the and operator is used to combine two conditions. The switch statement is much clearer, and there is no need for additional nested if statements.

csharp
public string DescribeNumber(int number) { return number switch { > 0 and < 10 => "Single-digit positive number", >= 10 and < 100 => "Two-digit positive number", <= 0 => "Zero or negative number", _ => "Number is too large" }; }

Properties Patterns

Property patterns allow you to match object properties rather than the object itself. This pattern is especially useful when you want to test the state of an object.

Example

In this example, the property pattern matches the Age property of the Person class. This makes it simple to classify a person based on their age without multiple condition checks.

csharp
public string DescribePerson(Person person) { return person switch { { Age: < 18 } => "Minor", { Age: >= 18, Age: < 65 } => "Adult", { Age: >= 65 } => "Senior", _ => "Unknown person" }; } public class Person { public string Name { get; set; } public int Age { get; set; } }

Positional Patterns

Positional patterns allow you to match the elements of a tuple or an object’s deconstructed form.

Example

In this example, the positional pattern is used to match the x and y coordinates of a point and deconstruct a tuple to describe its position in a two-dimensional plane.

csharp
public string DescribePoint((int x, int y) point) { return point switch { (0, 0) => "Origin", (0, _) => "On the Y-axis", (_, 0) => "On the X-axis", _ => "Somewhere in the plane" }; }

Benefits of Pattern Matching

The following are the benefits of pattern matching.

  1. Cleaner Code: It reduces the need for long if-else chains and voluble switch statements.
  2. Better Readability: The code becomes more understandable, focusing on the condition rather than how it’s checked.
  3. More Control: Patterns like relational and property patterns allow precise checks on values and object properties.
line

Copyrights © 2024 letsupdateskills All rights reserved