C# has always honored querying an object where you simply ask if it matches a particular class or interface, as in the following:

if (obj is SomeObject)
{
}

Unfortunately this was just about the limitation of the is statement, however, C# 7 has introduced the idea of pattern matching and is using the is construct, especially with case statements, as the cornerstone for a new type of development.

In the following example it will take the object parameter and check if it is an integer and will convert yourobj into the integer variable val. In this situation there is mercifully no need to use the awkward TryParse() method:

static void Convert(object yourobject)
{
    if (yourobject is int val)
    {
        val = val + 20;
    }
}

Pattern matching in switch statements

How long have switch statements been passé? Or is just really big switch statements that developers really frown at? Let's use this update as reset on our collective relationship with the switch.

So the first thing to state emphatically is that you can now switch on any object! You are no longer limited to primitive types, in fact each case statement can be filtered based on the pattern method, here are few examples we can look at:

static void Convert(object yourobj)
{
    switch(yourobj)
    {
        case Captcha c when c.Success == false && c.Count > 0:
            c.Success = true;
            break;
        case Captcha c:
            c.Success = false;
            break;
        case null:
            throw new ArgumentException();
        default:
            throw new ArgumentException(nameof(yourobj));
    }
}

Things to note in above example:-

  • We are using pattern matching to convert the object to variable c, the variable c only exists in the scope of the case statement (which is why I can define c twice).
  • The first case clause has a when condition to directly access and evaluate the properties of the object. In this case I created a Boolean expression to look at Success and Count properties and determine if I want to subsequently update other properties.
  • If the expression on the first case fails I go on to a later more permissive case that sets all other Captcha objects Success property to a value of false.
  • I still get to use default catch all case as you would with a switch on a primitive type.

I find these ideas really promising, and I imagine this is just the beginning of pattern matching.