使用Roslyn确定唯一标识符名称
本文关键字:标识符 唯一 Roslyn 使用 | 更新日期: 2023-09-27 18:13:19
使用Roslyn,我基于从我控制之外的代码解析的方法符号生成c#代码。因此,该方法可以有任意数量的参数。我生成的代码包括一个接受单个参数的lambda表达式,例如:
// I'm generating code like this
public void SomeMethod()
{
DoSomething(x => x.Foo());
}
这段代码的一个潜在问题是,如果包含方法包含一个名为x
的参数:
// my code generator might produce this
public void SomeMethod(int x)
{
DoSomething(x => x.Foo());
}
这段代码导致一个错误:
不能在此作用域中声明名为'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;
}
使用SemanticModel.LookupSymbols
似乎是一个好方法。这是Visual Studio将选定代码移动到新方法的方式。查看Roslyn的UniqueNameGenerator
内部类。
当你只有一个方法符号时,如何使用LookupSymbols
:你已经把生成的DoSomething(x => x.Foo());
添加到代码中了,所以你拥有的不仅仅是一个方法符号,不是吗?但是在任何情况下,您都可以从IMethodSymbol
中获得DeclaringSyntaxReferences
来访问相应的语法节点。