During my day job, I had a case where I needed to use some pattern matching to do some type checking. If you don’t know, pattern matching in C# allows you to test the type of an object and perform some additional “magic” at the same time. While having the chance to play around with this feature some questions arose from my usage.
I want to bring you through some steps in typical pattern matching usage, and we’ll ask some fun questions and test this feature to see how far we can bring it!
The common usage is by issuing type checking within an if statement.
Fair enough. Let’s move onto the next common usage of pattern matching.
Looks good. Very convenient and useful.
But, this is where my brain has some questions. The syntax [var] is [type] [newVar] is interesting. It is not really a statement. It’s an expression. But… it’s also a statement. Why?
This works. Each of these boolean values is set properly. In the official docs, the is operation is called the is expression. Fair enough.
This means we might be able to do this?
If exp is true and is is used with an if statement, varname is assigned and has local scope within the if statement only.
Alright. What if we did this?
That works and is a succinct way of expressing what we wanted to do.
Did you notice though - what Visual Studio says and what the docs say is actually not perfectly in harmony? Visual Studio says that the variable (for example) asLong is in scope - it just hasn’t been assigned. The docs say that when doing pattern matching in an if statement the variable is only in scope within the if statement only.
Let’s play around with this.
asLong = 5; // This compiles! asLong is in scope!
asInt = 5; // Fails! asInt is not in scope at all!
str = ""; // Fails! str is not in scope at all!
Weird. asLong is actually in the function / outer scope. But not the other variables. Must be the way the compiler chooses to modify the code.
Ok… let’s get super weird. Remember how in one of the code examples above we talked about the fact that the is operation is an expression?
Well, what do ya know! That works. Weird. Why?
// Really becomes something like this by the compiler.
// NOT this (like the docs say).
If we removed the last word of that statement, then it would be true. The variable doesn’t have local scope only within the if statement. But as it is, it’s technically false.
So - by being very technical and nit-picky - the docs are not totally 100% bang-on.
Does it matter? Not really. But, it’s fun to play around with this stuff.
Using the ternary operator in conjunction with the is pattern matching is handy and very compact. But in C# version 8 we are expecting something that takes this to a whole new level!
string str => // Do another thing!
Since this new usage of switch is an expression, you can return the result of that block of code. This should be great for things like the strategy pattern, factory patterns, etc.
In trying to push this feature as far as I could, I wrote some really weird code to figure out how the compiled code really works.
Yes, that compiles. The Console writes 5!
Changing the first line to object value = 5L; outputs 101.
Changing it to object value = 'g'; outputs 102.
This confirms our conclusions from the article above.
Nice. If you follow closely (ya, it’s hard to follow - I know…), this is exactly what my entire article was concluding.
What? That’s a mouthful. But, we can see that our conclusions about what it seemed like the compiler is doing are true.
Hopefully, you learned something new! Let me know what you think!
P.S. Here are some other articles you might enjoy!
How I Made LINQ 6X Faster Using A Functional Optimization!