如何从c#中的MethodCallExpression调用该方法

Eny*_*yra 20 .net c# parameters lambda

我有一个方法调用表达式并尝试调用该方法.我找到了一种方法,但是我在检索参数值方面遇到了问题,因为不是每个参数都用ConstantExpression描述.

Expression<Action<T>> = t => t.DoSomething(Par0, Par1, Par2);
MethodCallExpression methodCallExpression = selector.Body 
                                               as MethodCallExpression;

// get the information which is needed to invoke the method from the provided 
// lambda expression.
MethodInfo methodInfo = methodCallExpression.Method;
object[] arguments = methodCallExpression.Arguments.OfType<ConstantExpression>()
                            .Select(p => p.Value).ToArray();

// invoke the expression on every item within the enumerable
foreach (TSource item in source)
{ 
    methodInfo.Invoke(item, arguments);
}
Run Code Online (Sandbox Code Playgroud)

另外,我已经看到了一些其他方法来调用该方法,现在我不确定这是什么方法.

var func = expression.Compile();
var success = func.Invoke();
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,如何从中检索方法参数值methodCallExpression.Arguments

或者有更简单的方法来实现我的目标吗?

Dav*_*ier 26

您不必担心检索参数并自己调用MethodInfo,您可以让.NET为您执行此操作.您需要做的就是创建一个包含该方法的Lambda表达式.

例如.

MethodCallExpression expression = GetExpressionSomeHow();
object result = Expression.Lambda(expression).Compile().DynamicInvoke();
Run Code Online (Sandbox Code Playgroud)

这就是我在Linq提供程序中处理嵌套查询的方法.

编辑:实际上,看起来你可能已经在选择器变量中有一个LambdaExpression.在这种情况下,您应该能够直接编译并调用它:

object result = selector.Compile().DynamicInvoke();
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这更容易.我现在这样做://编译lambda表达式以获取调用委托.Action <TSource> action = selector.Compile(); //在可枚举的foreach(源代码中的TSource项)中的每个项目上调用表达式{action(item); 最后我还找到了这个问题的msdn文档:http://msdn.microsoft.com/en-us/library/bb882536.aspx (2认同)

小智 7

编译表达式是一个非常密集的操作,所以如果您计划重新使用表达式,我只会这样做.否则我会推荐反射方式; 你会发现它执行得更快.永远不要在紧密循环中调用expression.Compile().