什么是 Roslyn 中的 PatternSyntax

What is a PatternSyntax in Roslyn

这似乎是一个相当愚蠢的问题,我不确定它是否适合 Whosebug。

我的工具的用户报告了消息错误

Unable to cast object of type
'Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax' to type
'Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax'.

我不知道他的代码到底是什么样的(至少现在还不知道)。如果我可以编写一些包含 PatternSyntax 的代码,我也许能够重现该错误。

我的问题是,我不知道 C# 中的哪种语言构造会生成 PatternSyntax 类型的语法节点。

谁能帮我举个例子?

我相信这是从 Pattern Matching. The spec 生成的语法的一部分,因为此功能描述了语法以及更多示例。

PatternSyntax 定义在这里:http://sourceroslyn.io/Microsoft.CodeAnalysis.CSharp/Generated/Syntax.xml.Internal.Generated.cs.html#b554fa43e6090c28

以下继承自PatternSyntax

DiscardPatternSyntax
DeclarationPatternSyntax
VarPatternSyntax
RecursivePatternSyntax
ConstantPatternSyntax

我相信 VarPatternSyntax 的一个例子是 var o 如下:

static object CreateShape(string shapeDescription)
{
    switch (shapeDescription)
    {
        case var o when (o?.Trim().Length ?? 0) == 0:
            // white space
            return null;
        default:
            return "invalid shape description";
    }            
}

我们可以将上面的代码输入 RoslynQuoter 看看如何生成它,它看起来像这样:

CasePatternSwitchLabel(
            VarPattern(
                SingleVariableDesignation(
                    Identifier("o"))),
            Token(SyntaxKind.ColonToken))
        .WithWhenClause(
            WhenClause(
                BinaryExpression(
                    SyntaxKind.EqualsExpression,
                    ParenthesizedExpression(
                        BinaryExpression(
                            SyntaxKind.CoalesceExpression,
                            ConditionalAccessExpression(
                                IdentifierName("o"),
                                MemberAccessExpression(
                                    SyntaxKind.SimpleMemberAccessExpression,
                                    InvocationExpression(
                                        MemberBindingExpression(
                                            IdentifierName("Trim"))),
                                    IdentifierName("Length"))),
                            LiteralExpression(
                                SyntaxKind.NumericLiteralExpression,
                                Literal(0)))),
                    LiteralExpression(
                        SyntaxKind.NumericLiteralExpression,
                        Literal(0)))))))