C# > Functional Programming > Pattern Matching > switch Expression with Patterns
Switch Expression with Pattern Matching in C#
This snippet demonstrates the use of switch expressions combined with pattern matching in C#. Switch expressions provide a concise way to evaluate an expression and return a value based on different patterns. This is a powerful feature for handling complex logic in a clean and readable manner.
Basic Switch Expression with Type Pattern
This example showcases a simple switch expression that uses type patterns to determine the type of the 'shape' object. Based on the type (Circle or Rectangle), it returns a descriptive string. The 'null' case handles null objects, and the discard pattern '_' acts as a default case for any other type. This dramatically simplifies what would otherwise be a series of 'if-else' statements.
public static string GetShapeType(object shape)
{
return shape switch
{
Circle c => $"This is a Circle with radius {c.Radius}",
Rectangle r => $"This is a Rectangle with width {r.Width} and height {r.Height}",
null => "Shape is null",
_ => "Unknown shape"
};
}
public class Circle { public double Radius { get; set; } }
public class Rectangle { public double Width { get; set; } public double Height { get; set; } }
Property Pattern Matching
This example uses property patterns within the switch expression. It checks the properties 'TotalAmount' and 'IsNewCustomer' of the 'Order' object to determine the appropriate discount. The patterns allow you to specify conditions on properties directly within the switch cases, making the logic clear and easy to understand.
public static string GetDiscount(Order order)
{
return order switch
{
{ TotalAmount: > 1000, IsNewCustomer: true } => "20% discount",
{ TotalAmount: > 500 } => "10% discount",
{ IsNewCustomer: true } => "5% discount",
_ => "No discount"
};
}
public class Order { public decimal TotalAmount { get; set; } public bool IsNewCustomer { get; set; } }
Positional Pattern Matching
This example demonstrates positional pattern matching with records. The 'Order' is defined as a record, allowing you to deconstruct it into its positional parameters within the switch expression. This makes the code more concise and readable when dealing with records or tuples.
public static string GetOrderStatus(Order order)
{
return order switch
{
(> 1000, true) => "High Value New Customer",
(> 500, false) => "Valued Customer",
_ => "Regular Customer"
};
}
public record Order(decimal TotalAmount, bool IsNewCustomer);
Concepts Behind the Snippet
Pattern Matching: Pattern matching allows you to match expressions based on their structure or properties, rather than just their value. It offers a concise and readable way to handle complex conditional logic.
Switch Expressions: Switch expressions provide a more compact and expressive syntax compared to traditional switch statements. They return a value based on the matched pattern.
Records: Records are a concise way to define immutable data structures, often used with positional pattern matching.
Real-Life Use Case
Consider a scenario where you're building an e-commerce application. You can use switch expressions with pattern matching to calculate shipping costs based on the destination country, weight of the package, and value of the order. Different countries might have different shipping rates, and you can easily define these rules using pattern matching.
Best Practices
Interview Tip
Be prepared to explain the benefits of switch expressions with pattern matching over traditional 'if-else' statements. Highlight the increased readability, conciseness, and expressiveness. Also, understand the different types of patterns (type patterns, property patterns, positional patterns) and when to use them.
When to Use Them
Use switch expressions with pattern matching when you have complex conditional logic based on the structure or properties of an object. They are particularly useful when dealing with discriminated unions or data transfer objects.
Memory Footprint
The memory footprint of switch expressions with pattern matching is generally comparable to that of traditional 'if-else' statements. The compiler optimizes the code to minimize overhead. Records can have a slightly smaller memory footprint than traditional classes due to their value-based equality.
Alternatives
The primary alternative is using a series of 'if-else' statements. However, this can become cumbersome and less readable for complex logic. Another alternative is the visitor pattern, but it's often more complex to implement.
Pros
Cons
FAQ
-
What is the difference between a switch statement and a switch expression?
A switch statement is a traditional control flow statement that executes a block of code based on the value of an expression. A switch expression, on the other hand, is an expression that evaluates to a value based on pattern matching. Switch expressions are more concise and expressive. -
What is the discard pattern '_ ' in a switch expression?
The discard pattern '_' is a wildcard that matches any value. It's typically used as the default case in a switch expression to handle unexpected or unhandled inputs. -
Are switch expressions with pattern matching more performant than 'if-else' statements?
In most cases, the performance is comparable. The compiler optimizes both approaches. However, switch expressions with pattern matching can sometimes be slightly faster due to better branch prediction.