模式匹配案例何时

Ale*_*kiy 5 .net c# pattern-matching c#-7.0

我编写简单的数学标记器并尝试使用新的C#pattern matching功能.

Tokenizer非常简单:

    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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

是否有任何奇特的方式来执行此类操作?或者建议这样做的方法?

Dav*_*rno 2

有一种“奇特”的方法可以使用通常所说的活动模式来进行这样的模式匹配。虽然 C# 还不支持活动模式,但请参阅此答案,了解它们在实施时可能是什么样子的示例

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

switch (c)
{
    case Term(letterBuffer):
        ...
        break;
    case decimalSeparator:
    case Digit():
        ...
        break;
    case Operator():
        ...
        break;
}
Run Code Online (Sandbox Code Playgroud)

如果您希望在 C# 的未来版本中看到此功能,请在 csharplang github 存储库上投票

与此同时,你的选择是有限的,是坚持if其他人所说的陈述,还是像你一样使用“当守卫”。您选择哪一种实际上只是偏好风格的问题。