use*_*154 8 .net c# reflection methodinfo roslyn
如何从IMethodSymbol(Roslyn语法树)可靠地获取MethodInfo(反射).我可以从IMethodSymbol获取Type,并且该类型有许多方法,其中一个方法与IMethodSymbol实例匹配.
例如
int i = 0;
i.Equals(5);
Run Code Online (Sandbox Code Playgroud)
IMethodSymbol识别'等于'的地方
注意,[Int32]类型有2个[Equals]方法,一个采用[Object],另一个采用[Int32]参数.
我正在解析脚本,我没有任何工作区实例.
有任何想法吗?斯特沃
不可能从 IMethodSymbol可靠地获取 MethodInfo,因为您需要加载包含该方法所在类型的程序集,这可能是正在解析的脚本的情况,但可能不是代码的情况正在执行分析。
换句话说,您正在运行的脚本代码可能已加载程序集 X,其中包含具有方法 M 的类型 T(因此脚本代码可以具有调用方法 M 的代码),但分析器可能未加载程序集 X,并且因此它无法加载类型 T,因此它无法获取方法 M 的 MethodInfo 实例。
然而,对于像 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()
);
Run Code Online (Sandbox Code Playgroud)
值得注意的是,分析器通常是可移植的类库,无法访问完整的反射 API(这意味着上面的代码将无法工作),但如果您只是在项目中使用 Roslyn 来分析一些脚本,那么您可能会不必有这个限制。