Kirill Miroshnichenko.NET Developer

Pattern Matching in C# 7.0 and things you should know about it

20 July 2017

Every new version of C# language specification brings us something tasty to try, something that makes the developer’s life easier and the code more clean and understandable. Fortunately, version 7.0 is not an exception! With the following description, I’d like to show one of the great new features in C# 7.0 - Pattern Matching. In this article we will go through the new syntax in depth and see on the real examples how to use pattern matching and how it actually works.

With C# 7.0 we get a new conception of patterns. We can describe them as special language elements that help check values for specific characteristics and extract them.

Right now, pattern matching can be used in two existing language constructions:  switch-case, and is.  The patterns themselves can have the form of constants and types.  Additionally, when type patterns are used, the checked value can be immediately saved into a variable.

Let’s demonstrate all the new stuff with real examples.  Previously we did the following:

Here we check passed obj value against type (type pattern). With the new syntax the same can be done much easier:

From now we can do constant pattern matching:

But wait, there’s more! We can use a constant pattern when we don’t know the exact object type:

New possibilities naturally combine together:

Just look at this beautiful code! And imagine what you would have to  write without the new syntax. :/

Ok. Now it should be clear. But the interesting thing is what happens inside. Let’s compile and decompile it to understand how it actually looks without the syntax sugar:

Everything is quite simple, but it’s ugly…

In the example above, in the method DemoCat, we used a reference type. But what happens if we do pattern matching against a value type?

A value type cannot be used with the operator ‘as’ and cannot be translated the same way in the background as it was with the reference Cat object. But anyway, the new syntax somehow allows us to do the check, and it looks the same. And what actually happens is:

The compiler translates the matching expression through the nullable type.

Let’s move further. We can see more interesting examples when pattern matching is used in the switch-case construction. In the old version, only constants were allowed near the case and the switch itself supported only enums, strings and base types like int, bool, char, etc.

The following example demonstrates different kinds of pattern matching in the switch-case construction and its new features:

And traditionally, let’s look at the decompiled version:

Honestly, I don’t even want to try to understand what is happening there…

As you can see, pattern matching and the new syntax related to it help simplify life very much and make the code much cleaner. There are rumors that all this stuff will be even more extended in the next language versions. And now, try new stuff in your projects and may the force be with you!