作为 funcletizer 的一部分,我希望用它们的评估常量替换不包含参数的 c# 表达式:
double d = 100.0;
Expression<Func<double, double>> ex1 = x => -x;
Expression<Func<double>> ex2 = () => -d;
Expression result;
result = Funcletize(ex1); // should return ex1 unmodified
result = Funcletize(ex2); // should return Expression.Constant(-100.0)
我知道我可以通过将表达式包装在 lambda 表达式中并调用它来评估表达式:
object result = Expression.Lambda(ex2).Compile().DynamicInvoke();
// result == -100
当表达式包含未绑定的参数时,ex1
如上所述,这当然会失败,抛出 InvalidOperationException,因为我没有提供任何参数。如何检查表达式是否包含此类参数?
我当前的解决方案涉及 try{} catch(InvoalidOperationException),但这似乎是一种非常不雅且容易出错的方式:
// this works; by catching InvalidOperationException
public static Expression Funcletize(Expression ex)
{
try
{
// Compile() will throw InvalidOperationException,
// if the expression contains unbound parameters
var lambda = Expression.Lambda(ex).Compile();
Object value = lambda.DynamicInvoke();
return Expression.Constant(value, ex.Type);
}
catch (InvalidOperationException)
{
return ex;
}
}