假设我有这个InvocationExpression,GetDelegate<Func<double,double,double>>("Add")()
,我如何删除在ArgumentListSyntax中找到的打开/关闭parens?
我试图找出Node.ReplaceNodes&lt;&gt;()方法,但即便如此,我也不知道如何替换Nodes。
我正在检查this bit of sample code,他将整个节点撕成了组件,只是为了改变它。有没有更简单的方法来做到这一点?我找不到任何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
访问每个节点,所以我不确定如何将compilationUnit带入
答案 0 :(得分:3)
你无法用“删除parens”来思考它,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);