2016-08-12 2 views
2

Roslynリライタを使用しようとしていますが、IdentifierNameを式で置き換えることができません。Roslyn:IdentifierNameを式に置き換える方法

私はこのような交換を行うために訪問者をするときに理解したので、タイプに合わせる必要があります。型を無視してこの置換を行う回避策はありますか?あなたのケースで

return ((SyntaxNode)node).ReplaceNode(node, newExpr); 

ものの、ReplaceNode()は必要ありません。

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); 
    } 

} 

答えて

1

ReplaceNode()の戻り値の型がそうReplaceNode()SyntaxNodeにキャスト、投げないことを確認するために、そのthisパラメータと同じです新しい表現を返すだけで十分です。

return newExpr; 

両方とも上記のオプションは、IdentifierNameSyntaxが実際に指定された式で置き換えられる場合にのみ機能します。たとえば、foo();にあるすべてのIdentfierNameを置き換えると、かなり多くの式で動作します。 bar()の結果をbar()();とします。しかし、bar() x = bar()();は構文的に有効ではないため、var x = foo();に対して同じことを行うことはできません。

一方、別のIdentifierNameであるので、barのようなものを使用すると、いつでも動作します。 をvar x = foo();に設定すると、有効なツリーが表示されますが、無効なテキスト表現:barx = bar();が表示されるなど、必要な空白がなくなる可能性があります。そのあとで結果のツリーをフォーマットすることを忘れないでください。