我正在使用反射从类中读取所有属性和方法。所以我想用反射来识别方法的内部调用方法。我尝试使用'GetMethodBody()'方法读取MethodBody。但它只列出了局部变量。你能帮忙解决这个问题吗?
答案 0 :(得分:1)
您无法通过反射从MethodInfo
获取方法调用。
方法调用只是一个IL
指令,从反射的角度来看,所有只是IL
。加载参数的指令与调用方法的指令没有区别。
但是,你仍然可以在某些方面做到这一点。
Roslyn
来检查您的方法并搜索调用节点。IL
获取MethodBody
,对其进行解析,然后搜索call
或callvirt
指令,然后您需要解析操作数(token
在我们的例子中)并获得方法。这不是一种简单的方法,但您可以使用一些ILReader库来处理它。更新:
使用Roslyn,您有多种方法可以做到这一点。
您可以将方法设为MethodDeleration
并致电DescendantNodes().OfType<InvocationExpressionSyntax>()
。
您可以创建自定义CSharpSyntaxWalker
并覆盖VisitInvocationExpression
,然后使用CSharpSyntaxRewriter
执行相同操作。
根据您的需要,您无需重写某些内容,因此您需要在DescendantNodes
(直接前进)和CSharpSyntaxWalker
之间进行选择(更优雅,更强大的方式)。
您在StackOverflow和整个网络上都有很多示例。看看关于罗斯林的Josh Varty系列。 Github页面也是一个很好的资源。两个必须使用的工具是Quoter和TryRoslyn。同时检查SyntaxVisulaizer是否为VS。
IL解析方式更复杂(但不是那么多)。
在编写执行该操作的过程时,调用GetILAsByteArray()
然后需要解析字节以查找调用指令,然后获取指令操作数并解析为令牌。
对于所有这些,您可以使用一些现有的IL读卡器,例如this或this,当您找到所请求的说明时,您需要调用yourModule.ResolveMethod
来返回方法库。查看here和here了解示例