The first question on the subject we need to understand is about the syntax of the two constructions.
Although they both use the same keyword they are completely different. They took the name to not have to create another reserved word in the language, which would probably break several existing codes, but not have used one match
made a lot of people misunderstand this difference.
The first switch
is a syntactic sugar for if
and for all intents and purposes he is the same as a if
. The switch
traditional is not a if
, he’s a jump list, is an execution deviation optimization based on a possible value table, so it is very limited in what you can put there.
This is explained in How the switch works behind the scenes?. Language is different, but all who have this mechanism in the right way essentially work in the same way.
But C# was a little smarter and he did it even in the case of Pattern matching create a jump list optimized where you can do this. And even in a more organized way than was done with the switch
traditional.
It is possible to see that the CIL has specific instruction to mount the switch
and this will generate a code more suitable for the situation. See on Sharplab. Jitter will be responsible for assembling the most suitable real code to execute the need. Note that although the compiler does nothing on it itself, there is the possibility of Jitter doing more optimizations, so an instruction was created in CIL. So we can’t claim that the way more match of switch
C# is clearly inefficient, it will depend on the specific scenario and the implementation of Jitter.
Already the switch
is generated by the compiler creating the jump list "in hand". See on Sharplab..
See that the documentation clearly distinguishes the declaration switch
of the expression of match. This syntax of match was introduced in C# 6, and has been improving with each version.
Leandro’s response shows how to do with the match (expression switch
) to accept two values up to C# 8 (starting with 6 of course). For all intents and purposes it is a if
, there is no specific optimization, neither by the compiler (of course he does the best he can) nor will it be done later by Jitter. See on Sharplab.
I just don’t really like the other example that he put together because it generates unnecessary memory allocations. But that’s collateral to the matter we’re dealing with here.
The LINQ response shows another way to solve it and is available in C# 9 onwards. It is much easier to read and write. It also generates a different final code that can be optimized by Jitter, so it’s much more interesting than just being more "cute". See on Sharplab. Note that it tends to create a jump list even in this case, in a possibly equal or better way than the switch
traditional, just no guarantees for the language, will depend on the Jitter.
In fact, if we look at the final Jittado code in the implementation used, it generates a very efficient code. See on Sharplab. Seems more or less as efficient as the switch
traditional (looking over). But if you need the maximum optimization need to keep up with the end result, you can’t trust the compiler ever.
"Although they both use the same keyword they are completely different. They took advantage of the name to not have to create another reserved word in the language" I thought the same thing when I saw this Feature :) Good analysis, especially by the Sharplab links
– Ricardo Pontual