Pattern matching case when

.net, c#, c#-7.0, pattern-matching

Solution

There is a "fancy" way to do pattern matching like this, using what are commonly called active patterns. C# doesn't (yet) support active patterns though, but see this answer for an example of what they might look like if/when implemented.

So using active patterns, your code would end up looking something like:

switch (c)
{
    case Term(letterBuffer):
        ...
        break;
    case decimalSeparator:
    case Digit():
        ...
        break;
    case Operator():
        ...
        break;
}

If you'd like to see this feature in a future version of C#, please upvote it on the csharplang github repo.

In the meantime, then you are limited choosing between sticking with `if` statements as others have said, or using when guards as you are. Which you go for really is just a matter of preferred style.

Problem

I write simple math tokenizer and try to use new C# `pattern matching` feature. Tokenizer is quite simple: ``` public IEnumerable<IToken> Tokenize(string input) { const char decimalSeparator = '.'; string inputWithoutSpaces = input.Replace(" ", string.Empty); var numberBuffer = new StringBuilder(); var letterBuffer = new StringBuilder(); foreach (char c in inputWithoutSpaces) { switch (c) { case var _ when IsTerm(c, letterBuffer): if (numberBuffer.Length > 0) { yield return EmptyNumberBufferAsLiteral(numberBuffer); yield return new Operator('*'); } letterBuffer.Append(c); break; case decimalSeparator: case var _ when IsDigit(c): numberBuffer.Append(c); break; case var _ when IsOperator(c): if (numberBuffer.Length > 0) { yield return EmptyNumberBufferAsLiteral(numberBuffer); } if (letterBuffer.Length > 0) { yield return EmptyLetterBufferAsTerm(letterBuffer); } yield return new Operator(c); break; } } if (numberBuffer.Length > 0) { yield return EmptyNumberBufferAsLiteral(numberBuffer); } if (letterBuffer.Length > 0) { yield return EmptyLetterBufferAsTerm(letterBuffer); } } ``` I'm using `case var _` because I want to match by condition without using `if-else if` chain, but I'm unable to write `case when` without specifying `var variableName`. Is there any fancy way to perform such operation? Or it is recommended way to do these things?

Original source

Related problems