Reflection - Get the list of method calls inside a

2020-03-24 03:51发布

问题:

I am trying to find a way to get the list of method calls inside a lambda expression in C# 3.5. For instance, in the code below, I would like to method LookAtThis(Action a) to analyze the content of the lambda expression. In other words, I want LookAtThis to return me the MethodInfo object of Create.

LookAtThis(() => Create(null, 0));

Is it possible?

Thanks!

回答1:

This is fairly easy as long as you use Expression<Action> instead of Action. For full code, including how to get the actual values implied, see here - in particular ResolveMethod (and how it is used by Invoke). This is the code I use in protobuf-net to do RPC based on lambdas.



回答2:


using System;
using System.Linq;
using System.Diagnostics;
using System.Reflection;
using System.Linq.Expressions;

class Program {

static void Create(object o, int n) { Debug.Print("Create!"); }

static void LookAtThis(Expression<Action> expression)
{
    //inspect:
    MethodInfo method = ((MethodCallExpression)expression.Body).Method;
    Debug.Print("Method = '{0}'", method.Name);

    //execute:
    Action action = expression.Compile();
    action();
}

static void Main(string[] args)
{
    LookAtThis((Expression<Action>)(() => Create(null, 0)));
}

}



回答3:

static MethodInfo GetMethodInfo<T>(Expression<Func<T>> expression)
{
    return ((MethodCallExpression)expression.Body).Method;
}


回答4:

I think you'd need to use Expression Trees instead. See Expression Tree Visualizer Sample and How to: Implement an Expression Tree Visitor.



回答5:

Practically speaking, no this is not possible with reflection. Reflection is primarily aimed at providing meta data inspection information at runtime. What you're asking for is actual code inspection information.

I believe it is possible to get the actual bytes representing the IL for a method at runtime. However it would be just that, an array of bytes. You would have to manually interpret this into IL opcodes and use that to determine what methods were called. This is almost certainly not what you're looking for though.

It is possible though to use an expression tree lambda and analyze that for method calls. However this cannot be done on any arbitrary lambda expression. It must be done an an expression tree lambda expression.

http://msdn.microsoft.com/en-us/library/bb397951.aspx