语法节点中的ReplaceNodes<>()让我感到困惑

3

我正在尝试用我自己构建的InvocationExpressionSyntax节点替换一个InvocationExpressionSyntax节点。

到目前为止,我找到的唯一方法是使用SyntaxNode.ReplaceNodes<>,但我对它的工作原理感到困惑。

以下是代码片段:

public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
{
    InvocationExpressionSyntax replacementNode = (constructing my own invocation node, etc.

    node = (InvocationExpressionSyntax)node.ReplaceNodes(new List<InvocationExpressionSyntax>() { replacementNode /* ##Solution: This should be the EXISTING node, not the replacement node*/ }, new Func<InvocationExpressionSyntax, InvocationExpressionSyntax, SyntaxNode>((old, old2) =>
        {
            //return what?  old and old2 are both unmodified at this point. Doing another node.replacenodes in here doesn't work either. How do I replace node?
            //even the following doesn't work. 
            return replacementNode;
        }));
}

该方法的Func<>参数的元数据:

一个计算参数节点替换节点的函数。第一个参数是原始节点。第二个参数是已替换后代节点的相同节点。

我没有找到其他替换节点的方法。即使我返回我构建的替换节点,它仍然返回原始节点。

如何简单地替换整个节点?

2个回答

4

您的代码片段让我有一些困惑。ReplaceNodes替换了第一个参数中指定的节点,因此第一个参数应该是现有节点的列表,而不是新节点。您可以在第二个参数的lambda中创建新节点,并将其替换为树中的节点。如果您必须知道当前要替换的节点中的哪一个,请查看两个参数中的第一个参数(在您的示例中为“old”)以了解它是什么。


嘿,我想我比我想象中更困惑:D 那确实是我的问题。 - Kal_Torak
我仍然对 Func 如何处理第二个参数感到困惑。"用替换后的子代重写相同的节点"是什么意思?这是指它是第一个参数的副本吗?如果你还没有调用 ReplaceNodes,如何使用替换节点的第一个参数的副本? - JamesFaix
节点替换可以是递归的。考虑一种名为“交换参数”的特性,您可以重写方法调用以交换两个参数。如果您正在重写Call(Call(A, B), B),则会发生内部重写,然后将使用类似于Call(Call(B, A), B)的树来调用此函数。当它被外部调用时,“原始”节点将是原始起点,“重写”将是内部调用已被重写的位置。 - Jason Malinowski

2

这是我目前找到的解决方法替代方案:

node = node.WithExpression(replacementNode);

我认为这不是一种变通方法,而是正确的做法。 - svick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接