首页 > 解决方案 > c# Roslyn 从 ArgumentSyntax 获取 IParameterSymbol

问题描述

我有一个ArgumentSyntaxin some 调用表达式,我怎样才能在调用中得到IParameterSymbol对应IMethodSymbol

由于我已经看到ArgumentSyntax.NameColonSyntax,这意味着参数可能有一些名称,我不能用IParameterSymbol.Ordinal它们在它们的包含列表中的索引来匹配它们。

标签: c#roslynroslyn-code-analysis

解决方案


让我们看一下以下代码段:

public class Foo {
    public void Bar(int first, int second) {
        Add(first, second);
        Add(y: second, x: first);
    }
    
    public int Add(int x, int y) => x + y;
}

在这种情况下,该Add方法被调用两次,第一次使用序数参数,第二次使用命名参数。

如果我们尝试使用索引来获取参数,我们将不会在第二次调用中得到正确的结果。

解决此问题的一种方法(如果您事先知道名称)是尝试按名称获取参数并作为使用索引的备份:

private static ArgumentSyntax GetArgument(InvocationExpressionSyntax invocation, string name, int ordinal) =>
    GetArgument(invocation, name) ?? GetArgument(invocation, ordinal);

private static ArgumentSyntax GetArgument(InvocationExpressionSyntax invocation, string name) =>
    invocation.ArgumentList.Arguments
        .FirstOrDefault(argumentSyntax => argumentSyntax.NameColon?.Name.Identifier.Text == name);

private static ArgumentSyntax GetArgument(InvocationExpressionSyntax invocation, int ordinal) =>
    invocation.ArgumentList.Arguments[ordinal];

如果事先不知道参数名称,您可以获取方法符号:

var methodSymbol = (IMethodSymbol) semanticModel.GetSymbolInfo(invocations[0].Expression).Symbol;

查看声明语法参考:

var methodDeclarationSyntax = methodSymbol.DeclaringSyntaxReferences.First().GetSyntax() as MethodDeclarationSyntax;

并从声明中获取参数名称:

methodDeclarationSyntax.ParameterList.Parameters[0].Identifier.Text

但这只有在同一解决方案中声明方法时才有效。


推荐阅读