In this tutorial, you will learn all about the different ways you can perform pattern matching within .NET 7. While not brand new, for anyone like me who started using .NET way back when v1 was released, pattern matching was never a thing.

This all changed when C# 7 was released in 2017. Since C# 7, each new version of C# has been added to the pattern-matching capabilities and .NET 7 is no exception!

If you are looking for a guide that teaches you about the areas within your codebase where you can apply pattern matching, as well as understanding what patterns you can use you are in the right place. If you want to learn how to become a pattern-matching machine, read on 🔥🔥🔥

< hr/>

Wikipedia defines pattern matching as the act of checking a given sequence of tokens for the presence of the constituents of some pattern. In simpler terms, you can use pattern matching when you want to test that some data matches specific criteria. Typically, the use case for using pattern matching is when you need a quick and fast way to filter data contained within lists, collections, and even strings using a pattern match will often be easier than trying to write a custom function, or, even a lambda function.

You should consider pattern matching when you need to use either the is operator or a switch statement. When it comes to pattern matching, there are a number of patterns and techniques you can apply to these constructs. This list includes:

  • Constant pattern (released with C#7)
  • Declaration pattern (released with C#7)
  • Discard pattern (released with C#7)
  • Property pattern (released with C#8)
  • var pattern (released with C#8)
  • Positional pattern (released with C#8)
  • Tuple pattern (released with C#8)
  • Relational pattern (released with C#9)
  • Type pattern (released with C#9)
  • Logical patterns (released with C#9)
  • Extended Property Patterns (released with C#10)
  • List patterns (released with C#11)

When you first see the enormity of this list, you might think there is a bunch of new stuff to learn. The first point to consider is that these patterns can only be used when you are using is or switch. Some of the syntaxes are very similar between the patterns.
This is why this tutorial will go over a code example for each pattern explaining what it does! Before getting to the patterns, below outlines the classes that I will be using to test the theory:

Another feature worth covering is the switch expression. Introduced in C# 8, switch expressions are a more lightweight way of writing a switch statement. Within a switch expression, you can omit the case, break, and default keywords. As the name implies, this feature also converts a switch statement into an expression!

Constant pattern

Released in C#7, the constant pattern is probably the most basic pattern. Compare something to a constant. The most use-case for the constant pattern is testing an expression against null. Asides from null, you can also compare against things like boolean values (trueandfalse), and numbers like0`:

Declaration pattern

The declaration pattern will allow you to create an expression that at the run-time will match a given type and it successfully assigns the result to a declared variable. Sounds complex, but, in essence, you can create an expression and assign the successful result to a new variable:

Discard pattern

Discards are local variables that you can assign to, however, they cannot be read from. The discard pattern will allow you to define an expression where you can say you don't care about the pattern it matches on, or, you match on null. The most common case of the discard pattern is replacing the default case in a switch statement.

Property pattern

A property pattern match can occur when a comparison is not null and every pattern matches on a corresponding property on that type. In this pattern, a type is declared followed by some curly braces ({ }). Within the curly braces, additional pattern matching can be performed on the properties of the class:

Var pattern

The var pattern can be used for introducing a temporary variable inside an expression. The var pattern can be handy to bust out when you are performing some type of boolean expression, you need a temp variable to perform some additional conditional checking. For example:

Positional pattern

The deconstruct method is used to split a variable, such as a tuple, into two or more independent variables. An important part of making this work is implementing the void Deconstruct() without this you will encounter a compiler error!

The positional pattern is used to determine whether or not a deconstructed variable matches a user-defined nested pattern.

Tuple pattern

The tuple pattern is in essence a comma-separated list containing zero or more patterns that are enclosed in parentheses:

Relational pattern

Allows you to use relation operators (=, >, <, >=, <=) to test pattern

Type pattern

Logical pattern

We all know and love logical operators including and, or, and not. The logical pattern gives you the power to use these operators within patterns, as you can see:

Extended Property Patterns

You can reference nested properties or fields that are returned from a property pattern match:

List patterns

Happy Coding 🤘