使用反射从'MethodInfo'类中读取方法的内部调用方法名称

时间:2016-11-16 11:56:59

标签: .net reflection system.reflection

我正在使用反射从类中读取所有属性和方法。所以我想用反射来识别方法的内部调用方法。我尝试使用'GetMethodBody()'方法读取MethodBody。但它只列出了局部变量。你能帮忙解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

您无法通过反射从MethodInfo获取方法调用。

方法调用只是一个IL指令,从反射的角度来看,所有只是IL。加载参数的指令与调用方法的指令没有区别。

但是,你仍然可以在某些方面做到这一点。

  1. 您可以使用Roslyn来检查您的方法并搜索调用节点。
  2. 您可以从IL获取MethodBody,对其进行解析,然后搜索callcallvirt指令,然后您需要解析操作数(token在我们的例子中)并获得方法。这不是一种简单的方法,但您可以使用一些ILReader库来处理它。
  3. 更新:

    使用Roslyn,您有多种方法可以做到这一点。

    您可以将方法设为MethodDeleration并致电DescendantNodes().OfType<InvocationExpressionSyntax>()

    您可以创建自定义CSharpSyntaxWalker并覆盖VisitInvocationExpression,然后使用CSharpSyntaxRewriter执行相同操作。

    根据您的需要,您无需重写某些内容,因此您需要在DescendantNodes(直接前进)和CSharpSyntaxWalker之间进行选择(更优雅,更强大的方式)。

    您在StackOverflow和整个网络上都有很多示例。看看关于罗斯林的Josh Varty系列。 Github页面也是一个很好的资源。两个必须使用的工具是QuoterTryRoslyn。同时检查SyntaxVisulaizer是否为VS。

    IL解析方式更复杂(但不是那么多)。 在编写执行该操作的过程时,调用GetILAsByteArray()然后需要解析字节以查找调用指令,然后获取指令操作数并解析为令牌。

    对于所有这些,您可以使用一些现有的IL读卡器,例如thisthis,当您找到所请求的说明时,您需要调用yourModule.ResolveMethod来返回方法库。查看herehere了解示例