简体   繁体   中英

c# Roslyn get IParameterSymbol from ArgumentSyntax

I have an ArgumentSyntax in some invocation expression, how can I get corresponding IParameterSymbol in the IMethodSymbol of the invocation?

Since I have seen ArgumentSyntax.NameColonSyntax , which means the argument might have some name, I cannot use IParameterSymbol.Ordinal to match them by their index in their containing list.

Let's take a look at the following snippet:

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

In this case, the Add method is called twice, first with ordinal parameters and a second time with named parameters.

If we try to get the parameters by using the index we will not get the right result for the second call.

One way to solve this (if you know the name beforehand) is to try to get the argument by name and as a backup to use the index:

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];

If the parameter names are not know beforehand you can get the method symbol:

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

look at the declaring syntax references:

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

and get the parameter names from the declaration:

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

but this will work only if method is declared in the same solution.

I've been trying to figure out the same process myself and after fumbling a bit I found a path forward for this. It requires access to the SemanticModel . In my case it comes from the context of a Roslyn analyzer.

SemanticModel.GetOperation(argumentSyntaxNode) should return an IArgumentOperation which has a property IParameterSymbol Parameter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM