C# 7.0 introduced pattern matching with type tests, but it was limited to checking the type and extracting the value. Accessing properties required additional code after the pattern match.
C# 8.0 extends pattern matching to support property patterns and positional patterns, allowing you to match against object properties and nested structures directly within the pattern itself. This enables deeply nested pattern matching in a single expression.
Code
csharp
public decimal CalculateDiscount(Order order) => order switch
{
{ Customer: { IsVip: true }, IsFirstOrder: true } => 0.20m,
{ IsFirstOrder: true } => 0.10m,
{ Customer: { IsVip: true } } => 0.05m,
_ => 0m
};
public string Describe(object obj) => obj switch
{
Person { Address: { City: "London" } } => "Londoner",
Person { Name: var name } p when p.Age >= 18 => $"Adult named {name}",
Car { Make: "Nissan", Model: "Leaf" } => "Nissan Leaf",
_ => "Unknown"
};csharp
public decimal CalculateDiscount(Order order)
{
var isVip = order.Customer != null && order.Customer.IsVip;
if (isVip && order.IsFirstOrder)
return 0.20m;
if (order.IsFirstOrder)
return 0.10m;
if (isVip)
return 0.05m;
return 0m;
}
public string Describe(object obj)
{
if (obj is Person person)
{
if (person.Address?.City == "London")
return "Londoner";
if (person.Age >= 18)
return $"Adult named {person.Name}";
}
if (obj is Car car && car.Make == "Nissan" && car.Model == "Leaf")
return "Nissan Leaf";
return "Unknown";
}Notes
- Property patterns use the syntax
{ PropertyName: pattern }to match against object properties - You can nest patterns arbitrarily deep to match complex object structures
- Positional patterns work with types that have a
Deconstructmethod - Combine with switch expressions for concise, readable code
- Use
varpatterns to capture values:{ Name: var n }captures the Name property into variablen - Property patterns check for
nullbefore reading properties, so{ Customer: { IsVip: true } }is safe whenCustomeris null - C# 8.0 needs
whenclauses for comparisons; relational patterns such as>= 18arrived with pattern matching improvements C# 9.0 and dotted paths such as{ Customer.IsVip: true }with extended property patterns C# 10.0