我试图找到一种方法来获取C#3.5中lambda表达式中的方法调用列表。例如,在下面的代码中,我想方法LookAtThis(Action a)来分析lambda表达式的内容。换句话说,我希望LookAtThis返回Create的MethodInfo对象。
LookAtThis(() => Create(null, 0));
有可能吗?
谢谢!
答案 0 :(得分:4)
只要您使用Expression<Action>
代替Action
,这就相当容易。对于完整代码,包括如何获取隐含的实际值,see here - 特别是ResolveMethod
(以及Invoke
如何使用它)。这是我在protobuf-net中用来做基于lambdas的RPC的代码。
答案 1 :(得分: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)));
}
}
答案 2 :(得分:1)
static MethodInfo GetMethodInfo<T>(Expression<Func<T>> expression)
{
return ((MethodCallExpression)expression.Body).Method;
}
答案 3 :(得分:1)
我认为您需要使用Expression Trees代替。请参阅Expression Tree Visualizer Sample和How to: Implement an Expression Tree Visitor。
答案 4 :(得分:0)
实际上,反射不可能做到这一点。反射主要旨在在运行时提供元数据检查信息。您要求的是实际的代码检查信息。
我相信可以在运行时获取表示方法的IL的实际字节。然而,它只是一个字节数组。您必须手动将其解释为IL操作码并使用它来确定调用的方法。这几乎肯定不是你想要的。
虽然可以使用表达式树lambda并对方法调用进行分析。但是,这不能在任何任意lambda表达式上完成。必须完成一个表达式树lambda表达式。