Read a method's inner calling method names fro

2019-09-20 14:09发布

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?

1条回答
smile是对你的礼貌
2楼-- · 2019-09-20 14:39

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

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. 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.

Update:

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

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

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

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).

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.

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.

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

查看更多
登录 后发表回答