Ken*_*art 7 .net c# code-generation roslyn
使用Roslyn,我基于从我的控件之外的代码解析的方法符号生成C#代码.因此,该方法可以具有任意数量的参数.我生成的代码包含一个lambda表达式,它接受一个参数,例如:
// I'm generating code like this
public void SomeMethod()
{
DoSomething(x => x.Foo());
}
Run Code Online (Sandbox Code Playgroud)
此代码的潜在问题是如果包含方法包含一个名为的参数x:
// my code generator might produce this
public void SomeMethod(int x)
{
DoSomething(x => x.Foo());
}
Run Code Online (Sandbox Code Playgroud)
此代码导致错误:
无法在此范围内声明名为"x"的本地或参数,因为该名称用于封闭的本地范围以定义本地或参数
很公平.
为了解决这个问题,我想我可以从标识符名称开始x,用SemanticModel.LookupSymbols它来查看它是否已经定义.如果是这样,前置_(获取_x)并重复.
但这是最好的方法吗?如果是这样,LookupSymbols当我拥有的是方法符号时,如何使用?
我想到的另一个选择是Parameters在方法符号中使用该集合.我可以对它们执行相同的名称选择算法.但这样就够了吗?例如:
private static string GetIdentifierName(IMethodSymbol within)
{
var proposed = "x";
while (within.Parameters.Any(x => x.Name == proposed))
{
proposed = "_" + proposed;
}
return proposed;
}
Run Code Online (Sandbox Code Playgroud)
使用SemanticModel.LookupSymbols似乎是一个不错的方法。这是 Visual Studio 将选定代码移动到新方法的方式。查看UniqueNameGeneratorRoslyn 的内部类。
至于LookupSymbols当您拥有的只是一个方法符号时如何使用:您已经将生成的代码添加DoSomething(x => x.Foo());到代码中,因此您拥有的不仅仅是一个方法符号,不是吗?但无论如何,从 中IMethodSymbol您都可以DeclaringSyntaxReferences访问相应的语法节点。