问题描述
我正在使用反射从类中读取所有属性和方法.所以我想使用反射来识别方法的内部调用方法.我尝试使用 '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.
- 您可以使用
Roslyn
来检查您的方法并搜索调用节点. - 你可以从
MethodBody
获取IL
,解析它,然后搜索call
或callvirt
指令,然后你需要解析操作数(在我们的例子中是token
)并获取方法.这不是一个简单的方法,但您可以使用一些 ILReader 库来处理它.
- You can use
Roslyn
to go over your method and search for invocation nodes. - You can get the
IL
fromMethodBody
, parse it, and search forcall
orcallvirt
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 阅读器,例如 this 或 this 当你找出请求的指令时,你需要调用 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"类中读取方法的内部调用方法名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!