what's the use of the second parameter of the function parameter of ReplaceNodes extension method


  • i'm working with the ReplaceNodes extension method and so far i haven't found a use for the second parameter of it's function parameter. any info about it?

    2012年3月5日 18:13


  • Hi Ernesto - the documentation in intellisense describes this argument as follows -

    A function that computes a replacement node for the argument nodes. The first argument is the original node. The second argument is the same node rewritten with replaced descendents.

    Essentially, you could pass a lambda expression here to compute the replacement nodes for each encountered node. While computing the replacement for any given node inside this lambda expression, you would have access to both the corresponding unreplaced original node as well as the same node with any replacements on its descendents already performed. This is hard to describe precisely in words :) You could try running the below code example under the debugger to see how this works.

    using System;
    using System.Linq;
    using Roslyn.Compilers.CSharp;
    class Program
        static void Main(string[] args)
            var oldRoot = Syntax.ParseStatement("M(a, a);");
            var argList = oldRoot.DescendentNodes().OfType<ArgumentListSyntax>().First(); // '(a, a)'
            var firstArgument = argList.DescendentNodes().OfType<IdentifierNameSyntax>().First(); // first argument 'a'
            var invocationExpression = oldRoot.DescendentNodes().OfType<InvocationExpressionSyntax>().First(); // 'M(a, a)'
            var newRoot = oldRoot.ReplaceNodes(new SyntaxNode[] { firstArgument, invocationExpression }, 
                computeReplacementNode:(oldNode, newNode) =>
                    if (oldNode == firstArgument)
                        var replacedFirstArgument = Syntax.IdentifierName("b");
                        return replacedFirstArgument;
                    else if (oldNode == invocationExpression)
                        // At this point,
                        //    oldNode is the invocation expression with first and second argument unchanged (i.e. both are 'a')
                        //    newNode is the invocation expression with its first argument changed from 'a' to 'b' (inside the above if statement).
                        // Let us change the second argument from 'a' to 'b' as well.
                        var secondArgument = newNode.DescendentNodes().OfType<IdentifierNameSyntax>().Last();
                        var replacedSecondArgument = Syntax.IdentifierName("b");
                        var replacedInvocationExpression = newNode.ReplaceNode(secondArgument, replacedSecondArgument);
                        return replacedInvocationExpression;
                    return null;

    Hope this helps. Feel free to ask if you have additional questions around this.

    Shyam Namboodiripad | Software Development Engineer in Test | Roslyn Compilers Team

    2012年3月5日 22:24