【问题标题】:Determining a unique identifier name using Roslyn使用 Roslyn 确定唯一标识符名称
【发布时间】:2015-12-16 06:17:26
【问题描述】:

使用 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;
}

【问题讨论】:

  • 当我必须根据方法参数标识符进行验证时,我也使用了您的第二种方法。
  • 你还需要查看当地人。
  • @Slaks:我正在生成方法,所以我可以控制本地人(没有)。

标签: c# .net code-generation roslyn


【解决方案1】:

使用SemanticModel.LookupSymbols 似乎是一个不错的方法。这是 Visual Studio 将选定代码移动到新方法的方式。查看 Roslyn 中的 UniqueNameGenerator 内部类。

至于当你只有一个方法符号时如何使用LookupSymbols:你已经将生成的DoSomething(x => x.Foo()); 添加到代码中,所以你不仅仅是一个方法符号,不是吗?但无论如何,您可以从IMethodSymbol 获取DeclaringSyntaxReferences 以访问相应的语法节点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-24
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 2012-06-02
    • 2012-11-21
    • 1970-01-01
    相关资源
    最近更新 更多