我使用以下代码替换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);
但是当我这样做时,删除方法后换行,如果方法后面有#region
或#endregion
标记,则会发生错误。
例如
#region
static void RemoveRegions(string str)
{
return;
}
#endregion
更换身体后
#region
static void RemoveRegions(string str)
{
throw new NotImplementedException();
} #endregion // This cause to compiling error
答案 0 :(得分:12)
原始的BlockSyntax body
包含一些" Trailing Trivia"在紧密的大括号之后以空格(换行符)的形式。你构造的BlockSyntax newBody
也将包含一个紧密的大括号,但是大括号不知道它后面是否应该有任何空格。
你可以做三件事之一。我认为#1是最好的选择,但我列出其他完整性:
重用原始节点中的尾部琐事。您可以使用GetTrailingTrivia和WithTrailingTrivia来利用原始节点中的尾随琐事:
var originalTrailingTrivia = body.GetTrailingTrivia();
newBody = newBody.WithTrailingTrivia(originalTrailingTrivia);
在我看来,这是你最好的选择。它将通过保持任何尾随琐事(无论是一个空白行,五个空白行,零空行和两个空格,一个空格和一个注释等)来保留代码的布局。将更适合您尚未想到的其他场景。
格式化新节点。让内置的Formatter使用WithAdditionalAnnotations添加Formatter.Annotation并执行{{}来决定如何处理空白3}}在包含newBody
:
newBody = newBody.WithAdditionalAnnotation(Formatter.Annotation)
// Code that replaces this node back into the document
var formattedDocument = Formatter.Format(document, Formatter.Annotation);
请注意,这也将格式化方法的内容。您可以通过将Formatter.Annotation直接添加到关闭大括号本身而不是整个BlockSyntax并遵循相同的步骤来格式化仅关闭大括号和它周围的标记。这种方法可能会以合理的方式解决问题,但它会删除任何附加在大括号上的评论或故意奇怪的空白。
手动添加尾随换行符。手动创建换行符并使用WithTrailingTrivia将其添加到newBody
:
newBody = newBody.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);
这也将删除附加到近花括号的任何注释或故意奇怪的空格。它还会忽略所有上下文,并且不会遵循任何可能更改方法块所需布局的用户指定格式设置。
答案 1 :(得分:1)
Format
新节点,或添加SyntaxTrivia
。