本文介绍了使用反射从“MethodInfo"类中读取方法的内部调用方法名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was reading all properties and methods from a class using reflection. So i want to identify a method's inner calling methods using reflection. I tried to read MethodBody using 'GetMethodBody()' method. But it is listing only local variables. So could you please help on this?

推荐答案

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

You can't get method calls from MethodInfo by reflection.

方法调用只是一条IL指令,从反射的角度来看,一切都只是IL.加载参数的指令和调用方法的指令没有区别.

Method calls are just an IL instruction, from the reflection point of view all is just IL. There is no difference between instruction that load argument and instruction that call method.

但是,您仍然可以通过某些方式做到这一点.

But, you still can do that in some ways.

  1. 您可以使用 Roslyn 来检查您的方法并搜索调用节点.
  2. 你可以从MethodBody获取IL,解析它,然后搜索callcallvirt指令,然后你需要解析操作数(在我们的例子中是token)并获取方法.这不是一个简单的方法,但您可以使用一些 ILReader 库来处理它.
  1. You can use Roslyn to go over your method and search for invocation nodes.
  2. You can get the IL from MethodBody, parse it, and search for call or callvirt instruction, then you need to resolve the operand (token in our case) and get the method. This is not easy way but you can use some ILReader libraries to handle it.

更新:

对于 Roslyn,您有不止一种方法可以做到这一点.

With Roslyn, you have more than one way to do that.

您可以将您的方法作为 MethodDeleration 并调用 DescendantNodes().OfType().

You can take your method as MethodDeleration and call to DescendantNodes().OfType<InvocationExpressionSyntax>().

您可以创建一个自定义的 CSharpSyntaxWalker 并覆盖 VisitInvocationExpression 并且您可以使用 CSharpSyntaxRewriter 执行相同的操作.

You can create a custom CSharpSyntaxWalker and override VisitInvocationExpression and you do the same but with CSharpSyntaxRewriter.

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

For your needs you don't need to rewrite something so you need to choice between DescendantNodes (the straight forward way) and CSharpSyntaxWalker (the more elegant and powerful way).

您在 StackOverflow 和网络上有很多示例.查看关于 Roslyn 的 Josh Varty 系列.Github 页面也是一个很好的资源.两个必须使用的工具是 Quoter试试罗斯林.另请检查 VS 的 SyntaxVisulaizer.

You have a lot of examples here in StackOverflow and all over the web. Take a look at Josh Varty series about Roslyn. Also the Github page is a good resource. Two must use tools is Quoter and TryRoslyn. Also check SyntaxVisulaizer for VS.

IL 的解析方式比较复杂(但没那么复杂).当我编写程序来执行此操作时,调用 GetILAsByteArray() 然后您需要解析字节以找到调用指令,然后获取指令操作数并解析为令牌.

The IL parsing way is more complicated (but not so much).As I wrote the procedure to do that, is call to GetILAsByteArray() then you need to parse the bytes to find call instruction and then to take the instruction operand and resolve is token.

对于所有这些,您可以使用一些现有的 IL 阅读器,例如 thisthis 当你找出请求的指令时,你需要调用 yourModule.ResolveMethod 返回一个方法库.检查此处此处示例

For all of this you can use some existing IL Reader like this or this and when you figureout the requested instructions, you need to call yourModule.ResolveMethod that return you a method base. Check here and here for examples

这篇关于使用反射从“MethodInfo"类中读取方法的内部调用方法名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 09:41