C# > Functional Programming > Pattern Matching > Relational and Logical Patterns
Pattern Matching with Relational and Logical Patterns in C#
This snippet demonstrates how to use relational and logical patterns in C# for more expressive and concise conditional logic. These patterns allow you to match values against ranges and combine multiple conditions for more complex matching scenarios.
Code Snippet: Relational and Logical Patterns
This code defines two methods, `GetGrade` and `ClassifyTemperature`, demonstrating relational and logical patterns. `GetGrade` evaluates a numeric score and returns a letter grade using relational patterns (`>=`, `<`) and logical patterns (`and`). `ClassifyTemperature` takes a temperature and a boolean indicating whether it's Celsius. It then uses tuple patterns combined with relational and logical patterns to classify the temperature as Hot, Moderate, or Cold. The `Main` method showcases the usage with several example values.
using System;
public class PatternMatchingExample
{
public static string GetGrade(int score)
{
return score switch
{
>= 90 => "A",
>= 80 and < 90 => "B",
>= 70 and < 80 => "C",
>= 60 and < 70 => "D",
< 60 => "F",
_ => "Invalid Score"
};
}
public static string ClassifyTemperature(double temperature, bool isCelsius)
{
return (temperature, isCelsius) switch
{
(> 30, true) => "Hot (Celsius)",
(> 86, false) => "Hot (Fahrenheit)",
(>= 20 and <= 30, true) => "Moderate (Celsius)",
(>= 68 and <= 86, false) => "Moderate (Fahrenheit)",
(< 20, true) => "Cold (Celsius)",
(< 68, false) => "Cold (Fahrenheit)",
_ => "Unknown Temperature"
};
}
public static void Main(string[] args)
{
Console.WriteLine($"Grade for 95: {GetGrade(95)}"); // Output: A
Console.WriteLine($"Grade for 75: {GetGrade(75)}"); // Output: C
Console.WriteLine($"Temperature Classification: {ClassifyTemperature(32, true)}"); // Output: Hot (Celsius)
Console.WriteLine($"Temperature Classification: {ClassifyTemperature(50, false)}"); // Output: Cold (Fahrenheit)
}
}
Concepts Behind the Snippet
Pattern matching is a powerful feature introduced in C# 7.0 and enhanced in subsequent versions. It allows you to test an expression against a pattern and, if the expression matches the pattern, extract values from the expression. Relational patterns enable matching based on comparison operators (e.g., >, <, >=, <=). Logical patterns combine multiple patterns using logical operators like `and`, `or`, and `not` to create more complex matching conditions. Using `switch` expressions makes the code more readable and maintainable compared to nested `if-else` statements.
Real-Life Use Case
Relational and logical patterns are useful in scenarios where you need to categorize data based on ranges and multiple conditions. Consider a financial application that calculates tax brackets based on income. You could use relational and logical patterns to define different tax brackets based on income ranges and filing status. Another example is in game development to categorize the type of damage based on the magnitude of the impact and the materials involved.
Best Practices
Interview Tip
Be prepared to explain how pattern matching can improve code readability and maintainability. Highlight the benefits of using relational and logical patterns for complex conditional logic. Mention how these patterns can simplify code that would otherwise require nested `if-else` statements. Also, discuss the performance implications: while pattern matching is generally efficient, excessive complexity can impact performance, so strive for balance.
When to Use Them
Use relational and logical patterns when you need to:
Memory Footprint
Pattern matching itself doesn't introduce significant memory overhead. The memory footprint is primarily determined by the data types involved in the matching process. However, using complex patterns or extracting large amounts of data can indirectly increase memory usage. Optimize the complexity and data extraction to mitigate potential memory concerns.
Alternatives
Alternatives to relational and logical patterns include:
Pros
Cons
FAQ
-
What happens if none of the patterns match?
If none of the patterns match in a `switch` expression, the discard pattern (`_`) can be used as a default case. If no discard pattern is present and none of the patterns match, a `MatchError` exception is thrown. It's crucial to handle all possible cases to avoid unexpected errors. -
Can I use relational and logical patterns with other types besides numbers?
Yes, you can use relational and logical patterns with other types like strings and dates, provided that the types support the necessary comparison operators and logical operations. -
Are there performance considerations when using pattern matching?
While pattern matching is generally efficient, excessively complex patterns can impact performance. Simplify patterns where possible and avoid unnecessary computations within the matching logic.