模式匹配案例 when

Pattern matching case when

我编写了简单的数学分词器并尝试使用新的 C# pattern matching 功能。

分词器非常简单:

    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);
        }
    }

我正在使用 case var _,因为我想在不使用 if-else if 链的情况下按条件进行匹配,但是如果不指定 var variableName,我将无法编写 case when

有没有什么奇特的方法来执行这样的操作?或者推荐的方法来做这些事情?

有一种 "fancy" 方法可以像这样使用通常称为活动模式的模式进行模式匹配。 C# 不(还)支持活动模式,但是 .

因此使用活动模式,您的代码最终会看起来像:

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

如果您希望在未来的 C# 版本中看到此功能,please upvote it on the csharplang github repo

与此同时,您只能在坚持使用 if 语句(如其他人所说)或使用 when 守卫之间进行选择。至于你喜欢哪一种,只是喜欢的风格而已。