New C# 7 features in action: Pattern matching in C# 7 – Is expressions with patterns

Patterns in C# 7.0

Constant patterns (c): checks that the input is equal to constant expression

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if (creditCard is null) // constant pattern "null"
{
// Some code
}
if (creditCard is null) // constant pattern "null" { // Some code }
if (creditCard is null) // constant pattern "null"
{
	// Some code
}

Type patterns (T x): checks that the input is of type T, and if it is, then extracts the value of the input into a new variable x of type T

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if (card is AmericanExpress amex) // type pattern "AmericanExpress amex"
{
// Some code
}
if (card is AmericanExpress amex) // type pattern "AmericanExpress amex" { // Some code }
if (card is AmericanExpress amex) // type pattern "AmericanExpress amex"
{
	// Some code
}

Var patterns (var x): puts the value of the input into a new variable x with the same type as the input

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if (creditCard is var card) // var pattern "var card"
{
// Some code
}
if (creditCard is var card) // var pattern "var card" { // Some code }
if (creditCard is var card) // var pattern "var card"
{
	// Some code
}

In C# 7,  pattern matching is introduced to enhance:

  • is expressions
  • switch statements

Is expression with C# 7’s pattern matching enhancements

Simple Credit Card Processor Class

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
using System;
namespace SampleApplication
{
public interface ICard
{
bool IsValidCard { get; set; }
}
public class AmericanExpress : ICard
{
public bool IsValidCard { get; set; }
public bool ProcessAmexPayment(decimal amount)
{
throw new NotImplementedException();
}
}
public class Visa : ICard
{
public bool IsValidCard { get; set; }
public bool IsCreditCard { get; set; }
public bool ProcessVisaPayment(decimal amount)
{
throw new NotImplementedException();
}
public bool ProcessVisaCreditCardPayment(decimal amount)
{
throw new NotImplementedException();
}
}
public class MasterCard : ICard
{
public bool IsValidCard { get; set; }
public bool IsCreditCard { get; set; }
public bool ProcessMasterCardPayment(decimal amount)
{
throw new NotImplementedException();
}
public bool ProcessMasterCreditCardPayment(decimal amount)
{
throw new NotImplementedException();
}
}
}
using System; namespace SampleApplication { public interface ICard { bool IsValidCard { get; set; } } public class AmericanExpress : ICard { public bool IsValidCard { get; set; } public bool ProcessAmexPayment(decimal amount) { throw new NotImplementedException(); } } public class Visa : ICard { public bool IsValidCard { get; set; } public bool IsCreditCard { get; set; } public bool ProcessVisaPayment(decimal amount) { throw new NotImplementedException(); } public bool ProcessVisaCreditCardPayment(decimal amount) { throw new NotImplementedException(); } } public class MasterCard : ICard { public bool IsValidCard { get; set; } public bool IsCreditCard { get; set; } public bool ProcessMasterCardPayment(decimal amount) { throw new NotImplementedException(); } public bool ProcessMasterCreditCardPayment(decimal amount) { throw new NotImplementedException(); } } }
using System;

namespace SampleApplication
{
    public interface ICard
    {
        bool IsValidCard { get; set; }
    }

    public class AmericanExpress : ICard
    {
        public bool IsValidCard { get; set; }

        public bool ProcessAmexPayment(decimal amount)
        {
            throw new NotImplementedException();
        }
    }

    public class Visa : ICard
    {
        public bool IsValidCard { get; set; }

        public bool IsCreditCard { get; set; }
         
        public bool ProcessVisaPayment(decimal amount)
        {
            throw new NotImplementedException();
        }

        public bool ProcessVisaCreditCardPayment(decimal amount)
        {
            throw new NotImplementedException();
        }
    }

    public class MasterCard : ICard
    {
        public bool IsValidCard { get; set; }

        public bool IsCreditCard { get; set; }

        public bool ProcessMasterCardPayment(decimal amount)
        {
            throw new NotImplementedException();
        }

        public bool ProcessMasterCreditCardPayment(decimal amount)
        {
            throw new NotImplementedException();
        }
    }
}

Before C# 7: Sample code to explain the use of is expression in older versions of C#

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
namespace SampleApplication.CSharp6
{
public partial class CSharp6Sample
{
public static bool DoPayment(object creditCard, decimal amount)
{
if (creditCard == null)
{
return false;
}
if (amount == 0)
{
return false;
}
bool success = false;
if (creditCard is ICard)
{
var card = (ICard)creditCard;
if (card.IsValidCard == true)
{
if (card is AmericanExpress)
{
var amex = (AmericanExpress)creditCard;
success = amex.ProcessAmexPayment(amount);
}
else if (card is Visa)
{
var visa = (Visa)creditCard;
if (visa.IsCreditCard == false)
{
success = visa.ProcessVisaPayment(amount);
}
else
{
success = visa.ProcessVisaCreditCardPayment(amount);
}
}
else if (card is MasterCard)
{
var masterCard = (MasterCard)creditCard;
if (masterCard.IsCreditCard == false)
{
success = masterCard.ProcessMasterCardPayment(amount);
}
else
{
success = masterCard.ProcessMasterCreditCardPayment(amount);
}
}
}
}
return success;
}
}
}
namespace SampleApplication.CSharp6 { public partial class CSharp6Sample { public static bool DoPayment(object creditCard, decimal amount) { if (creditCard == null) { return false; } if (amount == 0) { return false; } bool success = false; if (creditCard is ICard) { var card = (ICard)creditCard; if (card.IsValidCard == true) { if (card is AmericanExpress) { var amex = (AmericanExpress)creditCard; success = amex.ProcessAmexPayment(amount); } else if (card is Visa) { var visa = (Visa)creditCard; if (visa.IsCreditCard == false) { success = visa.ProcessVisaPayment(amount); } else { success = visa.ProcessVisaCreditCardPayment(amount); } } else if (card is MasterCard) { var masterCard = (MasterCard)creditCard; if (masterCard.IsCreditCard == false) { success = masterCard.ProcessMasterCardPayment(amount); } else { success = masterCard.ProcessMasterCreditCardPayment(amount); } } } } return success; } } }
namespace SampleApplication.CSharp6
{
    public partial class CSharp6Sample
    {
        public static bool DoPayment(object creditCard, decimal amount)
        {
            if (creditCard == null)
            {
                return false;
            }

            if (amount == 0)
            {
                return false;
            }

            bool success = false;

            if (creditCard is ICard) 
            {
                var card = (ICard)creditCard;

                if (card.IsValidCard == true)
                {
                    if (card is AmericanExpress)
                    {
                        var amex = (AmericanExpress)creditCard;
                        success = amex.ProcessAmexPayment(amount);
                    }
                    else if (card is Visa)
                    {
                        var visa = (Visa)creditCard;

                        if (visa.IsCreditCard == false)
                        {
                            success = visa.ProcessVisaPayment(amount);
                        }
                        else
                        {
                            success = visa.ProcessVisaCreditCardPayment(amount);
                        }
                    }
                    else if (card is MasterCard)
                    {
                        var masterCard = (MasterCard)creditCard;

                        if (masterCard.IsCreditCard == false)
                        {
                            success = masterCard.ProcessMasterCardPayment(amount);
                        }
                        else
                        {
                            success = masterCard.ProcessMasterCreditCardPayment(amount);
                        }
                    }
                }
            }

            return success;
        }
    }
}

Modifications to the above sample code to use C# 7’s pattern matching to enhance the is expression

Note the use of pattern matching (in is expression)

  1. constant pattern
  2. type pattern
  3. type pattern with condition

in the below sample code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
namespace SampleApplication.CSharp7
{
public partial class CSharp7Sample
{
public static bool DoPayment(object creditCard, decimal amount)
{
if (creditCard is null) // constant pattern "null"
{
return false;
}
if (amount is 0) // constant pattern "0"
{
return false;
}
bool success = false;
if (creditCard is ICard card && card.IsValidCard == true) // type pattern "ICard card" with condition
{
if (card is AmericanExpress amex) // type pattern "AmericanExpress amex"
{
success = amex.ProcessAmexPayment(amount);
}
else if (card is Visa visa)
{
if (visa.IsCreditCard == false)
{
success = visa.ProcessVisaPayment(amount);
}
else
{
success = visa.ProcessVisaCreditCardPayment(amount);
}
}
else if (card is MasterCard masterCard)
{
if (masterCard.IsCreditCard == false)
{
success = masterCard.ProcessMasterCardPayment(amount);
}
else
{
success = masterCard.ProcessMasterCreditCardPayment(amount);
}
}
}
return success;
}
}
}
namespace SampleApplication.CSharp7 { public partial class CSharp7Sample { public static bool DoPayment(object creditCard, decimal amount) { if (creditCard is null) // constant pattern "null" { return false; } if (amount is 0) // constant pattern "0" { return false; } bool success = false; if (creditCard is ICard card && card.IsValidCard == true) // type pattern "ICard card" with condition { if (card is AmericanExpress amex) // type pattern "AmericanExpress amex" { success = amex.ProcessAmexPayment(amount); } else if (card is Visa visa) { if (visa.IsCreditCard == false) { success = visa.ProcessVisaPayment(amount); } else { success = visa.ProcessVisaCreditCardPayment(amount); } } else if (card is MasterCard masterCard) { if (masterCard.IsCreditCard == false) { success = masterCard.ProcessMasterCardPayment(amount); } else { success = masterCard.ProcessMasterCreditCardPayment(amount); } } } return success; } } }
namespace SampleApplication.CSharp7
{
    public partial class CSharp7Sample
    {
        public static bool DoPayment(object creditCard, decimal amount)
        {
            if (creditCard is null) // constant pattern "null"
            {
                return false;
            }

            if (amount is 0) // constant pattern "0"
            {
                return false;
            }

            bool success = false;

            if (creditCard is ICard card && card.IsValidCard == true) // type pattern "ICard card" with condition
            {
                if (card is AmericanExpress amex) // type pattern "AmericanExpress amex"
                {
                    success = amex.ProcessAmexPayment(amount);
                }
                else if (card is Visa visa)
                {
                    if (visa.IsCreditCard == false)
                    {
                        success = visa.ProcessVisaPayment(amount);
                    }
                    else
                    {
                        success = visa.ProcessVisaCreditCardPayment(amount);
                    }
                }
                else if (card is MasterCard masterCard)
                {
                    if (masterCard.IsCreditCard == false)
                    {
                        success = masterCard.ProcessMasterCardPayment(amount);
                    }
                    else
                    {
                        success = masterCard.ProcessMasterCreditCardPayment(amount);
                    }
                }
            }

            return success;
        }
    }
}

Happy Coding !!!

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *