【问题标题】:Why Roslyn is generating method code without spaces为什么 Roslyn 生成没有空格的方法代码
【发布时间】:2015-10-30 23:03:57
【问题描述】:

Roslyn 生成的代码在标识符和关键字之间没有任何空格,我做错了什么?它还在方法块的末尾放置了一个分号。 这是我的代码:

SeparatedSyntaxList<ParameterSyntax> parametersList = new SeparatedSyntaxList<ParameterSyntax>().AddRange
(new ParameterSyntax[]
    {
        SyntaxFactory.Parameter(SyntaxFactory.Identifier("sender")).WithType(SyntaxFactory.ParseTypeName("object")),
        SyntaxFactory.Parameter(SyntaxFactory.Identifier("args")).WithType(SyntaxFactory.ParseTypeName("EventArgs"))
    }
);

MethodDeclarationSyntax newMethod = SyntaxFactory.MethodDeclaration(
    SyntaxFactory.List<AttributeListSyntax>(),
    SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)),
    SyntaxFactory.ParseName("void"),
    null,
    SyntaxFactory.Identifier("simpleButton1_Click"),
    null,
    SyntaxFactory.ParameterList(parametersList),
    SyntaxFactory.List<TypeParameterConstraintClauseSyntax>(),
    SyntaxFactory.Block(),
    SyntaxFactory.Token(SyntaxKind.SemicolonToken)
);

这是我得到的结果:

privatevoidsimpleButton1_Click(objectsender,EventArgse){};

【问题讨论】:

    标签: c# roslyn


    【解决方案1】:

    为了更全面,应该提到NormalizeWhiteSpace。它将默认格式应用于给定节点:

    MethodDeclarationSyntax newMethod = SyntaxFactory.MethodDeclaration(
        SyntaxFactory.List<AttributeListSyntax>(),
        SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)),
        SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)),
        null,
        SyntaxFactory.Identifier("simpleButton1_Click"),
        null,
        SyntaxFactory.ParameterList(parametersList),
        SyntaxFactory.List<TypeParameterConstraintClauseSyntax>(),
        SyntaxFactory.Block(),
        null
      )
    
    newMethod = newMethod.NormalizeWhitespace();
    

    ToString() 将产生预期的输出:

    private void simpleButton1_Click(object sender, EventArgs args)
    {
    }
    

    【讨论】:

    • NormalizeWhitespace 适合我。它添加了空格(很多),但至少确保关键字和 id 之间有空格
    【解决方案2】:

    我认为将分号放在那里是因为您将分号传递给创建方法声明的方法,我猜这是在声明没有主体的抽象方法时使用的。

    要正确格式化输出,您可以使用 Microsoft.CodeAnalysis.Formatting 命名空间中的 Formatter 类。

    Workspace workspace = MSBuildWorkspace.Create();
    SyntaxNode formattedNode = Microsoft.CodeAnalysis.Formatting.Formatter.Format(newMethod, workspace);
    

    对于返回类型,您可以执行以下操作

    SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword));   
    

    这会给你一个TypeSyntax

    【讨论】:

      【解决方案3】:

      您可以使用.WithAdditionalAnnotations(Formatter.Annotation) 来格式化您生成的语法节点。

      【讨论】:

      • 感谢@Tamas 的建议,但它似乎不起作用。我从这个方法中得到的是,它会在我不想插入的方法上添加额外的注释。相反,我只想创建正确的方法语法。
      • 您在哪里生成此代码?这是在代码修复提供程序中吗?您在 Visual Studio 中吗?如果没有,您需要在要格式化的语法节点上使用Formatter.Format()
      • Formatter.Format 修复了参数部分,但方法声明仍然类似于“privatevoidButton1_Click”。 SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)) 定义的修饰符和SyntaxFactory.ParseName("void") 的 returnType 可能不是最好的方法。知道如何改进吗?顺便说一句,一个丑陋的 hack 是解析 " void " 而不是 "void" 以找到所需的结果
      猜你喜欢
      • 1970-01-01
      • 2022-01-23
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多