c# - 使用 Roslyn 获取方法参数

标签 c# .net roslyn

我可以使用以下代码从对特定方法的所有调用的解决方案中获取列表:

var createCommandList = new List<MethodSymbol>();
INamedTypeSymbol interfaceSymbol = 
   (from p
    in solution.Projects
    select p.GetCompilation().GetTypeByMetadataName(
        "BuySeasons.BsiServices.DataResource.IBsiDataConnection")
    ).FirstOrDefault();
foreach (ISymbol symbol in interfaceSymbol.GetMembers("CreateCommand"))
{
    if (symbol.Kind == CommonSymbolKind.Method
        && symbol is MethodSymbol)
    {
        createCommandList.Add(symbol as MethodSymbol);
    }
}
foreach (MethodSymbol methodSymbol in createCommandList)
{
    foreach (ReferencedSymbol referenceSymbol
        in methodSymbol.FindReferences(solution))
    {
        foreach (ReferenceLocation referenceLocation
            in from l
               in referenceSymbol.Locations
               orderby l.Document.FilePath
               select l)
        {
            if (referenceLocation.Location.GetLineSpan(false)
                    .StartLinePosition.Line ==
                referenceLocation.Location.GetLineSpan(false)
                    .EndLinePosition.Line)
            {
                Debug.WriteLine("{0} {1} at {2} {3}/{4} - {5}",
                    methodSymbol.Name,
                    "(" + String.Join(",",
                       (from p
                        in methodSymbol.Parameters
                        select p.Type.Name + " " + p.Name).ToArray()
                       ) + ")",
                Path.GetFileName(referenceLocation.Location.GetLineSpan(false)
                    .Path),
                referenceLocation.Location.GetLineSpan(false)
                    .StartLinePosition.Line,
                referenceLocation.Location.GetLineSpan(false)
                    .StartLinePosition.Character,
                referenceLocation.Location.GetLineSpan(false)
                    .EndLinePosition.Character));
            }
            else
            {
                throw new ApplicationException("Call spans multiple lines");
            }
        }
    }
}

但这给了我一个 ReferencedSymbol 的列表。虽然这给了我调用该方法的文件和行号,但我还想获得调用该方法的特定参数。我如何才能转换我拥有的信息或使用 Roslyn 获得相同的信息? (请注意,我首先使用 Solution.Load 方法加载解决方案,然后循环查找定义/声明该方法的位置 (createCommandList))。

最佳答案

您已经在此处使用 Roslyn。当您有一个 referenceSymbol 时,您可以获取方法声明语法,然后向下查看树以获取参数列表。

我插入了一个使用您的referenceSymbolarguments 变量:

// Snip start
foreach (MethodSymbol methodSymbol in createCommandList)
{
    foreach (ReferencedSymbol referenceSymbol
        in methodSymbol.FindReferences(solution))
    {
        var arguments = referenceSymbol.Definition.DeclaringSyntaxNodes.First()
            .DescendantNodes().OfType<ParameterSyntax>().ToList();

        foreach (ReferenceLocation referenceLocation in
            from l
            in referenceSymbol.Locations
            orderby l.Document.FilePath
            select l)
        {
// Snip end

当您执行调试输出时,您可以使用该参数列表来获取名称。

我的解决方案需要获取 DeclaringSyntaxNodesFirst(),我不太喜欢它,但找不到另一种方法来获取语法树。

关于c# - 使用 Roslyn 获取方法参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11264058/

相关文章:

c# - 为什么我可以将 null 分配给类型 "struct Nullable<T>"的值而不是我的结构?

c# - 如何将 IMethodSymbol 转换为 MethodDeclarationSyntax?

.net - 为什么 roslyn 分析器需要是可移植组件?

c# - Azure WebJobs 'Run Command' 如何设置?

.net - 性能更新 - WPF 中更好的图像帧速率

C#将按位运算符作为参数传递

c# - 在 C# 中从 Web 检索匿名类型

c# - 如何覆盖 WCF Restful 服务中的方法?

c# - "is"表达式的结果在运行时返回 false,但在检查时返回 true