众所周知,Roslyn语法树是不可变的,因此在进行更改后,您需要获得一个新节点。
我正在尝试使用文档编辑器更新文档,但我一直收到错误,即在语法树中找不到该节点。
public static T FindEquivalentNode<T>(this Document newDocument, T node)
where T : CSharpSyntaxNode
{
var root = newDocument.GetSyntaxRootAsync().Result;
return root.DescendantNodes().OfType<T>()
.FirstOrDefault(newNode => SyntaxFactory.AreEquivalent(newNode, node));
}
当我尝试再次调用文档编辑器时:
var newFieldDeclaration = documentEditor.GetChangedDocument().FindEquivalentNode(syntaxNode);
documentEditor.ReplaceNode(newFieldDeclaration, propertyDeclaration);
我收到错误:
节点不是树的一部分
newField声明不为null它找到一个等效的字段但我仍然得到这个错误,我该如何替换这个节点?
答案 0 :(得分:2)
您获得节点是因为在您的FindEquivalentNode
方法中,您正在这样做:
SyntaxFactory.AreEquivalent(newNode, node)
SyntaxFactory.AreEquivalent
对于&#34;真实&#34;不会返回true相同的节点,但对于结构中似乎相等的节点\令牌(考虑topLevel
参数)。
回到你的问题,如果你想致电ReplaceNode
,你必须拥有&#34;真实&#34;旧节点,所以你不会得到
节点不是树的一部分
要实现这一点,你有几个选择,其中一个是@Tamas在评论中写的,使用SyntaxAnnotations
。
示例:
//Add annotation to node
var annotation = new SyntaxAnnotation("your_annotation", "some_data");
node = node .WithAdditionalAnnotations(annotation);
// Now you can change the tree as much you want
// And when you want to get the node from the changed tree
var annotatedNode = someNode.DescendantNodesAndSelf().
FirstOrDefault(n => n.GetAnnotations("your_annotation").Any())