替换方法的主体将删除以下换行符

Ali*_*.Kh 5 c# roslyn

我正在使用以下代码来替换Roslyn的方法体;

/* method is instance of MethodDeclarationSyntax */
BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();"));
BlockSyntax body = method.Body;
var modifiedMethod = method.ReplaceNode(body, newBody);
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时,删除方法后换行,如果方法后面有一个#region#endregion标记,则会发生错误.

例如

    #region
    static void RemoveRegions(string str)
    {
        return;
    }
    #endregion
Run Code Online (Sandbox Code Playgroud)

并在更换身体后

    #region
    static void RemoveRegions(string str)
    {
        throw new NotImplementedException();
    }        #endregion    // This cause to compiling error
Run Code Online (Sandbox Code Playgroud)

Dav*_*chl 15

原始的BlockSyntax body在紧密的大括号之后以空格(换行符)的形式包含一些"尾随的琐事".您构造的BlockSyntax newBody也将包含一个紧密的大括号,但该大括号不知道它后面是否应该有任何空格.

你可以做三件事之一.我认为#1是最好的选择,但我列出其他完整性:

  1. 从原始节点重用尾随琐事.您可以使用GetTrailingTriviaWithTrailingTrivia来利用原始节点中的尾随琐事:

    var originalTrailingTrivia = body.GetTrailingTrivia();
    newBody = newBody.WithTrailingTrivia(originalTrailingTrivia);
    
    Run Code Online (Sandbox Code Playgroud)

    在我看来,这是你最好的选择.它将保留代码的布局,通过保留任何尾随的琐事(无论是一个空白行,五个空白行,零空白行和两个空格,一个空格和一个注释等),并将更适合其他你尚未想到的场景.

  2. 格式化新节点.让内置的格式化程序决定如何使用处理空白WithAdditionalAnnotations添加Formatter.Annotation和执行Formatter.FormatAsync在包含树newBody:

    newBody = newBody.WithAdditionalAnnotation(Formatter.Annotation)
    // Code that replaces this node back into the document
    var formattedDocument = Formatter.Format(document, Formatter.Annotation);
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,这也将格式化方法的内容.您可以通过将Formatter.Annotation直接添加到close大括号本身而不是整个BlockSyntax并遵循相同的步骤来格式化紧密的大括号和它周围的标记.这种方法可能会以合理的方式解决问题,但它会删除任何注释或附加在紧密花括号上的故意奇怪的空白.

  3. 手动添加尾随换行符.手动创建换行符并将其添加到newBodyWithTrailingTrivia:

    newBody = newBody.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);
    
    Run Code Online (Sandbox Code Playgroud)

    这也将删除任何附加到大括号上的注释或故意奇怪的空格.它还会忽略所有上下文,并且不会遵循任何可能更改方法块所需布局的用户指定格式设置.


Kev*_*lch 1

要么是Format新节点,要么是添加SyntaxTrivia到它。