Pattern matching in C# – part 1

In my previous post, I tried to explain what pattern matching is, and in particular the F# match expression, that I’m trying to mimic in C#. For my first attempt, I’ll try to analyse the matching cases that can apply on a single value. Let’s start right now with an F# sample[1]:

What is difficult here is to write something that is valid C#, because:

I can’t change the compiler,

To keep things simple, I don’t want to use Roslyn in the first attempt (although that might come later).

Recording expressions for individual tests

This solution is mainly based upon a generic class called PatternMatcher<TSource, TResult>, which represents the match expression being built. Each Case overload builds an instance of a MatchCase class. As with many “fluent” syntax nowadays, in order to chain the calls in a single statement, each Case overload returns a new instance of the PatternMatcher, which keeps track of all the cases registered so far.

The MatchCase’s sole purpose is to encapsulate two expressions:

a test expression that will be used to determine if a particular source value matches the case: this will be an expression of Func<TSource, bool>,

a selector expression that will be used to produce the result of the match expression when the input value matches this particular case: this will be an expression of Func<TSource, TResult>.

Getting an Expression of a given Func type is nothing more that changing the type of a variable. The compiler will change its work accordingly, and produce an Expression from a given lambda-expression, instead of a typed delegate.

The most general case is the conditional pattern. Let’s take a look at the following extension method:

An expression corresponding to the previous code could be generated, but I also want to handle an additional case: when there is no match. This means that my expression has to be able to return some result or… none. Some or none ? Isn’t there a type for that ? We’ll see how to use it next time.

[1] I know this sample is useless and theoretical, but isn’t this whole series ? If you really want to use match expressions, embrace F#, not C# !