ICYMI C# 8 New Features: Simplify If Statements with Property Pattern Matching

This is part 3 in a series of articles.

In the first part of this series we looked at switch expressions.

When making use of switch expressions, C# 8 also introduced the concept of property pattern matching. This enables you to match on one or more items of an object and helps to simplify multiple if..else if statements into a more concise form.

For example, suppose we had a CustomerOrder:

class CustomerOrder
{
    public string State { get; set; }
    public bool IsVipMember { get; set; }
    // etc.
}

And we created an instance of this:

var order1 = new CustomerOrder
{
    State = "WA",
    IsVipMember = false
};

Now say we wanted to calculate a delivery cost based on what State the order is being delivered to. If the customer is a VIP member then the delivery fee may be waived depending on what the State is. We could write this using if…else if:

if (order1.State == "WA" && order1.IsVipMember)
{
    deliveryCost = 0M;
}
else if (order1.State == "WA" && !order1.IsVipMember)
{
    deliveryCost = 2.3M;
}
else if (order1.State == "NT" && !order1.IsVipMember)
{
    deliveryCost = 4.1M;
}
else
{
    deliveryCost = 5M;
}

The preceding code will get bigger and harder to read the more states we add.

An alternative could be to use a switch statement to try and simplify this:

decimal deliveryCost;

switch (order1.State, order1.IsVipMember)
{
    case ("WA", true):
        deliveryCost = 0M;
            break;
    case ("WA", false):
        deliveryCost = 2.3M;
        break;
    case ("NT", false):
        deliveryCost = 4.1M;
        break;
    default:
        deliveryCost = 5M;
        break;
}

In the preceding code there is still a bit of “ceremony” with all the case blocks.

We could instead use a switch expression that makes use of property pattern matching:

deliveryCost = order1 switch
{
    { State: "WA", IsVipMember: true } => 0M,
    { State: "WA", IsVipMember: false } => 2.3M,
    { State: "NT", IsVipMember: false } => 4.1M,
    _ => 5M
};

Notice how the preceding code is a lot more succinct, and it’s easy to see all the cases and combinations.

What if for some States, the VIP status was not relevant for calculating delivery cost?

Suppose that the state “QE” always had a high delivery cost that never got reduced even for VIPs:

deliveryCost = order1 switch
{
    { State: "WA", IsVipMember: true } => 0M,
    { State: "WA", IsVipMember: false } => 2.3M,
    { State: "NT", IsVipMember: false } => 4.1M,
    { State: "QE"} => 99.99M,
    _ => 5M
};

In the preceding code, if the State is “QE” then the delivery cost will be 99.99. Also notice the use of the discard _ that says “for all other combinations not listed above set the delivery cost to 5”.

If you want to fill in the gaps in your C# knowledge be sure to check out my C# Tips and Traps training course from Pluralsight – get started with a free trial.

SHARE:

Comments (2) -

  • Leszek

    2/12/2021 4:12:13 PM | Reply

    Hi,
    Good tips. Thank you very much.

    • Jason Roberts

      3/5/2021 2:32:17 AM | Reply

      No worries - glad to help Smile

Add comment

Loading