Browsing posts in: .NET

Pattern Matching in C# 7

Pattern matching is a powerful way to check the value and type of a variable at run time while also deconstructing the value being matched on so it can be used if needed. This can be more useful when developing software using functional programming techniques. They arise from functional programming’s disjoint unions/algebraic data types and are used to manipulate the control flow of a function.

C# 7 introduced pattern matching in switch statements. Previously it was only possible to check the value of a variable against a constant value. Consider the standard switch statement below:

public static void SwitchStatementNoMatching()
{
     var x = 1;
     switch (x)
     {
          case 1:
          Console.WriteLine("The value is 1!");
          break;
          case 2:
          Console.WriteLine("The value is 2!");
          break;

          default:
          Console.WriteLine("No action defined for the value provided!");
          break;
     }
}

First a variable x is defined as the integer value 1. Then the switch statement compares the value of x against the integer values 1 or 2. If x is not 1 or 2 the default case is reached.

In the pattern matching example below, notice that the behavior of the switch statement depends on not only the value of the variable, but the type as well.

public static void SwitchStatementWithMatching(object x)
{
     switch (x)
     {
          case int newInt32x:
          Console.WriteLine("The value is {0} and it is an integer!", newInt32x);
          break;</pre>
<pre>          case string newStringx:
          Console.WriteLine("The value is {0} and it is a string!", newStringx);
          break;

          default:
          Console.WriteLine("No action defined for the variable provided!");
          break;
     }
}

The switch statement above is very similar to the first example with some minor syntactic changes. The switch statement is operating on the value x that is passed in to the function, but this time it is unknown if the variable x will be a string or integer (or other type). The switch checks to see if the x is an int and also defines a new integer variable that will be defined if that particular case statement matches.

In addition to checking the type of a variable in the match expression, a when clause can be added to also check the value of the variable.

public static void SwitchStatementWithMatchingAndWhen(object x)
{
     switch (x)
     {
          case int newInt32x when newInt32 == 1:
          Console.WriteLine("The value is {0} and it is an integer!", newInt32x);
          break;</pre>
<pre>          case string newStringx when newStringx == "Hello World!":
          Console.WriteLine("The value is {0} and it is a string!", newStringx);
          break;

          default:
          Console.WriteLine("No action defined for the variable provided!");
          break;
     }
}

In this example the switch statements are not only checking the type of x (integer or string) but also the values (1 or “Hello World!”).

One thing to keep in mind when using pattern matching like this is the order of the case statements become much more important. For example, if the first case statement checks for all integers and then the second checks for an integer whose value is 1, the second case statement would never be reached because it would be caught by the first.