Roslyn:如何用表达式替换标识符名称
Roslyn: How to replace an IdentifierName with an Expression
我正在尝试使用 Roslyn 重写器,但无法用表达式替换标识符名称。
据我了解,当访问者进行此类替换时,他们需要在类型上匹配。是否有任何解决方法可以忽略类型来执行此替换?
public class NameRewriter : CSharpSyntaxRewriter
{
private readonly ExpressionSyntax newExpr;
public NameRewriter(ExpressionSyntax newExpr) {
this.newExpr = newExpr;
}
public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node) {
return node.ReplaceNode(node, newExpr);
}
}
ReplaceNode()
的 return 类型与其 this
参数相同,因此要确保 ReplaceNode()
不抛出,将其转换为 SyntaxNode
:
return ((SyntaxNode)node).ReplaceNode(node, newExpr);
虽然在您的情况下,根本不需要 ReplaceNode()
,但只需 return 新表达式就足够了:
return newExpr;
只有当 IdentifierNameSyntax
可以用给定的表达式实际替换时,以上两个选项才有效。例如,替换 foo();
中的所有 IdentfierName
将适用于几乎任何表达式,例如使用 bar()
结果是 bar()();
。但是对 var x = foo();
做同样的事情是行不通的,因为 bar() x = bar()();
在句法上是无效的。
另一方面,使用 bar
之类的东西应该可以随时使用,因为它是另一个 IdentifierName
。
此外,这样做可能会使您缺少所需的空格,例如,在 var x = foo();
上使用 bar
会生成有效的树,但文本表示无效:barx = bar();
。所以不要忘记在之后格式化生成的树。
我正在尝试使用 Roslyn 重写器,但无法用表达式替换标识符名称。
据我了解,当访问者进行此类替换时,他们需要在类型上匹配。是否有任何解决方法可以忽略类型来执行此替换?
public class NameRewriter : CSharpSyntaxRewriter
{
private readonly ExpressionSyntax newExpr;
public NameRewriter(ExpressionSyntax newExpr) {
this.newExpr = newExpr;
}
public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node) {
return node.ReplaceNode(node, newExpr);
}
}
ReplaceNode()
的 return 类型与其 this
参数相同,因此要确保 ReplaceNode()
不抛出,将其转换为 SyntaxNode
:
return ((SyntaxNode)node).ReplaceNode(node, newExpr);
虽然在您的情况下,根本不需要 ReplaceNode()
,但只需 return 新表达式就足够了:
return newExpr;
只有当 IdentifierNameSyntax
可以用给定的表达式实际替换时,以上两个选项才有效。例如,替换 foo();
中的所有 IdentfierName
将适用于几乎任何表达式,例如使用 bar()
结果是 bar()();
。但是对 var x = foo();
做同样的事情是行不通的,因为 bar() x = bar()();
在句法上是无效的。
另一方面,使用 bar
之类的东西应该可以随时使用,因为它是另一个 IdentifierName
。
此外,这样做可能会使您缺少所需的空格,例如,在 var x = foo();
上使用 bar
会生成有效的树,但文本表示无效:barx = bar();
。所以不要忘记在之后格式化生成的树。