0

假设我有这个 InvocationExpression, GetDelegate<Func<double,double,double>>("Add")(),我将如何删除 ArgumentListSyntax 中的 Open/Close 括号?
我试图找出 Node.ReplaceNodes<>() 方法,但即使这样,我也不知道如何用任何东西替换节点。

我正在检查这段示例代码,他将整个节点撕成组件,只是为了改变它。没有更简单的方法可以做到这一点吗?我找不到任何 Node.RemoveNode()方法。

我也试图做这样的事情,但没有成功:

argNodeMinusParen = argNodeMinusParen.WithArgumentList(argNodeMinusParen .ArgumentList.ReplaceToken(Syntax.Token(SyntaxKind.OpenParenToken), Syntax.Token(SyntaxKind.WhitespaceTrivia)));

澄清: 我正在尝试修改这个 InvocationExpression :

GetDelegate<Func<double,double,double>>("Add")()

GetDelegate<Func<double,double,double>>("Add")

我试图解决的问题:

从这段代码开始。

    private void Init()
    {
        StoredMethods.Add("Add", /*new InvocationExpression for identical signature method as controller.Add*/);
        StoredMethods.Add("Mul", /*new InvocationExpression for identical signature method as controller.SubMember.Mul*/);
    }

    private void RandomMethod()
    {
        var result = controller.SubMember.Mul(2, 3);
        var result2 = controller.Add(5, 5);
        var result3 = controller.Add(controller.SubMember.Mul(4, 5), 6);
        var result4 = controller.Subtract(5, controller.Add(1, 1));
    }

    public Dictionary<string, InvocationExpressionSyntax> StoredMethods
    {
        get;
        set;
    }

我想把它变成这个。请注意这只是半伪代码,我实际上正在做一堆更复杂的静态泛型类型的东西,为了清楚起见,这被简化了。

对于在整个项目中找到的每个调用,如果在 StoredMethods 中找到方法名称,则将调用替换为 StoredMethod 调用。结果应该是这样的:

    private void RandomMethod()
    {
        var result = StoredMethods.GetDelegate("Mul")(2, 3);
        var result2 = StoredMethods.GetDelegate("Add")(5, 5);
        var result3 = StoredMethods.GetDelegate("Add")(StoredMethods.GetDelegate("Mul")(4, 5), 6);
        var result4 = controller.Subtract(5, StoredMethods.GetDelegate("Add")(1, 1));
    }//Notice that Subtract was NOT substituted, because it wasn't in StoredMethods, where Add was replaced in the inner arg

我更大的问题是试图弄清楚如何处理嵌套/组合的类和成员。我认为递归可以处理多个 MemeberAccess 表达式,但我很难将问题分解以解决问题。另外,我SyntaxRewriter用来访问每个节点,所以我不确定如何将编译单元带入其中

4

1 回答 1

3

你不能用“删除括号”来思考它,Roslyn 不是关于字符,而是关于语法树。如果您将表达式视为树的一部分,您会发现它具有两个相关属性:

  • Expression, 表示GetDelegate<Func<double,double,double>>("Add")
  • ArgumentList, 那代表().

所以,你想要的是Expression(在innerInvocation变量中):

var code = "GetDelegate<Func<double,double,double>>(\"Add\")()";
var outerInvocation = (InvocationExpressionSyntax)Syntax.ParseExpression(code);
var innerInvocation = (InvocationExpressionSyntax)outerInvocation.Expression;

如果调用是一些较大代码的一部分,并且您想删除那里的括号,则需要使用Replace()

var compilationUnit = …;

// or some other code to locate the invocation
var outerInvocation = compilationUnit.DescendantNodes()
                                     .OfType<InvocationExpressionSyntax>()
                                     .First();
var innerInvocation = (InvocationExpressionSyntax)outerInvocation.Expression;

var newCompilationUnit = compilationUnit.ReplaceNode(
    outerInvocation, innerInvocation);
于 2012-07-30T07:46:05.750 回答