Рослин получает MethodInfo от IMethodSymbol

как я могу надежно получить MethodInfo (отражение) из IMethodSymbol (синтаксическое дерево Roslyn). Я могу получить Type из IMethodSymbol, а у этого типа много методов, один из которых соответствует экземпляру IMethodSymbol.

e.g.

int i = 0;
i.Equals(5);

где IMethodSymbol идентифицирует «равно»

Обратите внимание, что существует 2 метода [Equals] для типа [Int32], один из которых принимает и [Object], а другой принимает параметр [Int32].

Я разбираю скрипты, у меня нет экземпляров рабочей области.

Есть идеи? Стево


person user1275154    schedule 29.05.2015    source источник


Ответы (1)


Невозможно надежно получить MethodInfo из IMethodSymbol, потому что вам нужно загрузить сборку, содержащую тип, на котором находится метод, что может иметь место для анализируемого скрипта, но может не для кода, выполняющего анализ.

Другими словами, код скрипта, который вы выполняете, может содержать загруженную сборку X, содержащую тип T с методом M (и поэтому код скрипта может содержать код, вызывающий метод M), но анализатор может не загружена сборка X, поэтому он не загружает тип T и поэтому не получает экземпляр MethodInfo для метода M.

Однако для такой сборки, как System, скорее всего, можно с уверенностью сказать, что вы можете получить к ней доступ из кода анализатора.

Итак, все, что вам нужно сделать, это получить пространство имен и имя типа для типа, у которого есть метод, и получить для него экземпляр TypeInfo. Затем используйте GetMethod, передав ему имя метода и типы аргументов, чтобы получить MethodInfo. Что-то вроде этого:

var invocation = (InvocationExpressionSyntax)context.Node;
var methodSymbol = (IMethodSymbol)context.SemanticModel.GetSymbolInfo(invocation).Symbol;
var declaringTypeName = string.Format(
    "{0}.{1}",
    methodSymbol.ContainingType.ContainingAssembly.Name,
    methodSymbol.ContainingType.Name
);
var methodName = methodSymbol.Name;
var methodArgumentTypeNames = methodSymbol.Parameters.Select(
    p => p.Type.ContainingNamespace.Name + "." + p.Type.Name
);
var methodInfo = Type.GetType(declaringTypeName).GetMethod(
    methodName,
    methodArgumentTypeNames.Select(typeName => Type.GetType(typeName)).ToArray()
);

Стоит отметить, что анализаторы часто представляют собой переносимые библиотеки классов, которые не имеют доступа к API полного отражения (это означает, что приведенный выше код не будет работать), но если вы просто используете Roslyn в проекте для анализа некоторых скриптов, то вы, вероятно, не обязательно иметь это ограничение.

person Dan Roberts    schedule 25.06.2016