我正在使用以下代码来替换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是最好的选择,但我列出其他完整性:
从原始节点重用尾随琐事.您可以使用GetTrailingTrivia和WithTrailingTrivia来利用原始节点中的尾随琐事:
var originalTrailingTrivia = body.GetTrailingTrivia();
newBody = newBody.WithTrailingTrivia(originalTrailingTrivia);
Run Code Online (Sandbox Code Playgroud)
在我看来,这是你最好的选择.它将保留代码的布局,通过保留任何尾随的琐事(无论是一个空白行,五个空白行,零空白行和两个空格,一个空格和一个注释等),并将更适合其他你尚未想到的场景.
格式化新节点.让内置的格式化程序决定如何使用处理空白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并遵循相同的步骤来仅格式化紧密的大括号和它周围的标记.这种方法可能会以合理的方式解决问题,但它会删除任何注释或附加在紧密花括号上的故意奇怪的空白.
手动添加尾随换行符.手动创建换行符并将其添加到newBodyWithTrailingTrivia:
newBody = newBody.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);
Run Code Online (Sandbox Code Playgroud)
这也将删除任何附加到大括号上的注释或故意奇怪的空格.它还会忽略所有上下文,并且不会遵循任何可能更改方法块所需布局的用户指定格式设置.