Expression.Lambda()的参数问题

更新:这确实有效,我是愚蠢的:(

我有以下扩展方法

public static string ExtMethod(this object self, object myparameter); 

在运行时,这可以通过多种方式调用,我认为这些都是可能的:

 Expression<Func> expr = x => x.property.ExtMethod(5); Expression<Func> expr = x => x.property.ExtMethod(new object()); Expression<Func> expr = x => x.property.ExtMethod(someMethod()); Expression<Func> expr = x => x.property.ExtMethod(x.someMethod()); Expression<Func> expr = x => x.property.ExtMethod(x.OtherProperty); 

我需要做的是评估“ myparameter ”,给出“ expr ”和“ T

因为在myparameter使用x的两种情况,我认为我需要创建一个表单的委托:

 Expression<Func> 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 🙁

在这些情况下,如果我这样做:

 var myparam = Expression.Lambda(myparameterExpr).Compile().Invoke(someT) 

它工作正常。

我该如何解决这个问题?

谢谢

好; 深究它; 在线:

 var myparam = Expression.Lambda(myparameterExpr).Compile().Invoke(someT); 

如果你没有尝试传入someT ,这将适用于那些在参数中不涉及x的表达式; 对于那些做的人,你需要告诉lambda包含参数(原始lambda中的相同参数) – 只需:

 var myparam = Expression.Lambda(myparameterExpr, outerLambda.Parameters[0]).Compile().Invoke(someT); 

这是一些评估内部参数的工作代码(给定参数类型的实例); 请注意,即使它涉及x ,我也会使用该参数 – 否则,它会对实例做什么?

 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(x => x.Bar.ExtMethod(5), foo); Test(x => x.Bar.ExtMethod(new object()), foo); Test(x => x.Bar.ExtMethod(someMethod()), foo); Test(x => x.Bar.ExtMethod(x.someMethod()), foo); Test(x => x.Bar.ExtMethod(x.OtherProperty), foo); } static void Test(Expression> 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>( 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(); } } 

如果你检查expr.Parameters.Count并且它是0,如果没有参数调用怎么办?