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