Getting Setup With C# 9
If you aren’t sure you are using C# 9 and/or you want to start using some of the new shiny features in the C# language, be sure to read our quick guide on getting setup with C# 9 and .NET 5. Any feature written about here is available in the latest C# 9 preview and is not a “theoretical” feature, it’s ready to go!
C# 9 Features
We are slowly working our way through all new C# 9 features, if you are interested in other new additions to the language, check out some of the posts below.
- Improved Target Typing
- Relational Pattern Matching (this post!)
- Init Only Properties
- Top Level Programs
- Record Types
What We Currently Have
I remember reading the words “relational pattern matching” and kinda skipping over the feature because I wasn’t really sure what it was (And so, my developer brain said it can’t be that important!). But when I eventually found actual examples of it in action, I couldn’t believe that C# hadn’t had this feature yet.
So first, let’s mock up a problem in C# 8 that we should be able to solve with Relational Pattern Matching in C# 9 to actually be able to see the power.
Let’s take the following code :
int myValue = 1; if (myValue <= 0) Console.WriteLine("Less than or equal to 0"); else if (myValue > 0 && myValue <= 10) Console.WriteLine("More than 0 but less than or equal to 10"); else Console.WriteLine("More than 10");
How could we improve it? Well, I would probably still use the If/Else jumble from above in most cases just for it’s simplicity, but if you wanted to, you could use the Pattern Matching introduced in C# 7 with a switch statement. That would look something like this :
switch(myValue) { case int value when value <= 0: Console.WriteLine("Less than or equal to 0"); break; case int value when value > 0 && value <= 10: Console.WriteLine("More than 0 but less than or equal to 10"); break; default: Console.WriteLine("More than 10"); break; }
Not bad but we don’t really add anything to the If/Else statements, in fact we actually add even more complexity. If we are using C# 8, then we can use Switch Expressions (A great introduction here if you’ve never seen Switch Expressions before : https://dotnetcoretutorials.com/2019/06/25/switch-expressions-in-c-8/). That would instead look something like :
var message = myValue switch { int value when value <= 0 => "Less than or equal to 0", int value when value > 0 && value <= 10 => "More than 0 but less than or equal to 10", _ => "More than 10" }; Console.WriteLine(message);
This actually looks pretty good. But there is *so* much verbose stuff going on here that surely we can clean up right?
Adding The “is”/”and” Keywords
This actually isn’t specific to our example, but C# 9 has introduced the “is” and “and” keywords (We’re going to do an entire article on these in the future because there is actually some really cool stuff you can do). And these can actually help us here, we can now change this :
if (myValue > 0 && myValue <= 10) Console.WriteLine("More than 0 but less than or equal to 10");
To this :
if (myValue is > 0 and <= 10) Console.WriteLine("More than 0 but less than or equal to 10");
It’s just some sugar around saying “take this value and then I can do 1 to N statements on it all at once”. In long IF statements where you check multiple different options for a single variable/property, this is a huge help.
So obviously we can rewrite our If/Else statement from above to look like so :
if (myValue <= 0) Console.WriteLine("Less than or equal to 0"); else if (myValue is > 0 and <= 10) Console.WriteLine("More than 0 but less than or equal to 10"); else Console.WriteLine("More than 10");
And while that middle statement is a bit tidier, overall we are still writing quite a bit.
Relational Pattern Matching In Switch Statements/Expressions
Now we are cooking with gas. In C# 9, we can now turn this big case statement :
case int value when value > 0 && value <= 10:
Into this :
case > 0 and <= 10:
So we can do away with setting our variable for the pattern, and then add in our new “and” keyword to make things even tidier. That turns our entire switch statement into this :
switch(myValue) { case <= 0: Console.WriteLine("Less than or equal to 0"); break; case > 0 and <= 10: Console.WriteLine("More than 0 but less than or equal to 10"); break; default: Console.WriteLine("More than 10"); break; }
Pretty tidy! But we can take it further with our switch expression :
var message = myValue switch { <= 0 => "Less than or equal to 0", > 0 and <= 10 => "More than 0 but less than or equal to 10", _ => "More than 10" }; Console.WriteLine(message);
Holy moly that’s tidy! And that’s relational pattern matching with C# 9!
Troubleshooting
If at any point you get the following errors :
The feature 'and pattern' is currently in Preview and *unsupported*.
The feature 'relational pattern' is currently in Preview and *unsupported*.
It means you are using a version of C# less than 9. Check out our quick guide on getting setup with using C# 9 and all it’s features here : https://dotnetcoretutorials.com/2020/08/07/getting-setup-with-c-9-preview/