2015-09-19 14 views
6

Roslynを使用して、私のコントロール外のコードから解析されたメソッドシンボルに基づいてC#コードを生成しています。したがって、このメソッドは任意の数の引数を持つことができます。Roslynを使用して一意の識別子の名前を決定する

// my code generator might produce this 
public void SomeMethod(int x) 
{ 
    DoSomething(x => x.Foo()); 
} 

このコード:

// I'm generating code like this 
public void SomeMethod() 
{ 
    DoSomething(x => x.Foo()); 
} 

このコードの潜在的な問題を含む方法がxと呼ばれるパラメータが含まれている場合:私は生成コードのような、単一の引数を取りラムダ式を含みますエラーが発生します:

A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

これを回避するには、識別子名xで始まり、SemanticModel.LookupSymbolsを使用してそれがすでに定義されているかどうかを確認できると思っていました。その場合は、_の前に(_xを入力して)繰り返します。

これが最善の方法ですか?もしそうなら、LookupSymbolsは、私が持っているものがメソッドシンボルであればどうすればよいですか?

もう1つの方法は、メソッドシンボルにParametersコレクションを使用することだけでした。代わりにそれらに対して同じ名前選択アルゴリズムを実行することができました。しかしこれで十分でしょうか?たとえば:

private static string GetIdentifierName(IMethodSymbol within) 
{ 
    var proposed = "x"; 

    while (within.Parameters.Any(x => x.Name == proposed)) 
    { 
     proposed = "_" + proposed; 
    } 

    return proposed; 
} 
+0

メソッドのパラメータ識別子と照合しなければならないときは、2番目の方法も使用しました。 –

+0

地元の人もチェックする必要があります。 – SLaks

+0

@スラクス:私はメソッドを生成しているので、私は地元の人たちをコントロールしている(存在しない)。 –

答えて

1

SemanticModel.LookupSymbolsを使用して良い方法のように思えます。これは、Visual Studioが選択したコードを新しいメソッドに移動する方法です。 Roslynの内部クラスUniqueNameGeneratorをチェックしてください。

LookupSymbolsの使い方は、メソッド記号がすべての場合:既にコードにDoSomething(x => x.Foo());というコードを追加しているだけなので、方法記号以外にもありますよね?しかしいずれにしても、IMethodSymbolからDeclaringSyntaxReferencesに対応する構文ノードにアクセスすることができます。

関連する問題