Expression.Lambda()的参数问题 [英] Parameter problem with Expression.Lambda()
问题描述
更新:确实有效,我当时很蠢:(
我具有以下扩展方法
public static string ExtMethod(this object self, object myparameter);
在运行时,可以通过多种方式调用它,我认为这些都是可能的:
at runtime this is called in any number of ways ways, i think these are all possibilities:
Expression<Func<T, string>> expr = x => x.property.ExtMethod(5);
Expression<Func<T, string>> expr = x => x.property.ExtMethod(new object());
Expression<Func<T, string>> expr = x => x.property.ExtMethod(someMethod());
Expression<Func<T, string>> expr = x => x.property.ExtMethod(x.someMethod());
Expression<Func<T, string>> expr = x => x.property.ExtMethod(x.OtherProperty);
我需要做的是在给定"expr
"和"T
"的情况下评估"myparameter
"
what i need to do is evaluate the "myparameter
", given "expr
" and a "T
"
由于在myparameter
中使用x
的两种情况,我认为我需要创建以下形式的委托:
because of the two cases where x
is used in myparameter
, i thought i needed to create a delegate of the form:
Expression<Func<T, object>> expr = x => [myparameter expression here]
我认为这会起作用:
var extMethodExpr = expr.Body as MethodCallExpression;
var myparameterExpr = extMethodExpr.Arguments[1];
var myparam = Expression.Lambda(myparameterExpr, expr.Parameters).Compile().Invoke(someT)
但是对于不涉及x
的表达式,我得到 TargetParameterCountException
:(
but for the expressions that do not involve x
, i get TargetParameterCountException
:(
在这些情况下,如果我这样做:
in these cases, if i do:
var myparam = Expression.Lambda(myparameterExpr).Compile().Invoke(someT)
它工作正常.
我该如何解决?
谢谢
推荐答案
确定;陷入困境在该行中:
OK; got to the bottom of it; in the line:
var myparam = Expression.Lambda(myparameterExpr).Compile().Invoke(someT);
如果您不尝试传递someT
,则对那些在参数中不包含x
的表达式都适用;对于那些这样做的人,您需要告诉lambda包含参数(与原始lambda相同)-只需:
If you weren't trying to pass in a someT
, this would work for those expressions that don't involve x
in the argument; for those that do, you need to tell the lambda to include the parameter (the same one from the original lambda) - simply by:
var myparam = Expression.Lambda(myparameterExpr,
outerLambda.Parameters[0]).Compile().Invoke(someT);
这是一些评估内部参数的工作代码(给定参数类型的实例);请注意,即使不包含x
,我也会使用该参数-否则,它将对实例做什么?
Here's some working code that evaluates the inner parameter (given an instance of the argument type); note that I use the parameter even if it doesn't involve an x
- otherwise, what would it do with the instance?
using System;
using System.Linq.Expressions;
using System.Reflection;
class Foo {
public string Bar {get;set;}
public int someMethod() { return 4; }
public int OtherProperty { get { return 3; } }
}
static class Program
{
static int someMethod() { return 3; }
static void Main()
{
Foo foo = new Foo();
Test<Foo>(x => x.Bar.ExtMethod(5), foo);
Test<Foo>(x => x.Bar.ExtMethod(new object()), foo);
Test<Foo>(x => x.Bar.ExtMethod(someMethod()), foo);
Test<Foo>(x => x.Bar.ExtMethod(x.someMethod()), foo);
Test<Foo>(x => x.Bar.ExtMethod(x.OtherProperty), foo);
}
static void Test<T>(Expression<Func<T, string>> expr, T instance)
{
if (expr.Body.NodeType != ExpressionType.Call)
{
throw new InvalidOperationException("Call expected");
}
var call = ((MethodCallExpression)expr.Body);
if (call.Method != typeof(Program).GetMethod(
"ExtMethod", BindingFlags.Static | BindingFlags.NonPublic))
{
throw new InvalidOperationException("ExtMethod expected");
}
// we know that ExtMethod has 2 args; pick myParameter (the 2nd);
// then build an expression over arg, re-using our outer param
var newLambda = Expression.Lambda<Func<T, object>>(
call.Arguments[1], expr.Parameters[0]);
// evaluate it and show the argument value
object value = newLambda.Compile()(instance);
Console.WriteLine(value);
}
static string ExtMethod(this object self, object myParameter) {
return self.ToString();
}
}
这篇关于Expression.Lambda()的参数问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!