这可能对一些人来说很熟悉。我有一个包装类
所以这是我想要做的事情:
我已经尝试了几种方法将二进制表达式 bex 转换为 lambda,但到目前为止都没有成功。我希望能得到一些建议和指针。请注意,操作数可能是其他表达式对象,并且只有在树的叶子节点上它们才会是 ParameterExpression 或 ConstantExpression。
谢谢。
Ex
,用一堆隐式转换和运算符包装表达树。这里是简化版。public class Ex
{
Expression expr;
public Ex(Expression expr)
{
this.expr = expr;
}
public static implicit operator Expression(Ex rhs) { return rhs.expr; }
public static implicit operator Ex(double value)
{ return new Ex(Expression.Constant(value, typeof(double))); }
public static implicit operator Ex(string x)
{ return new Ex(Expression.Parameter(typeof(double), x)); }
public static Ex operator +(Ex left, Ex right)
{
return new Ex(Expression.Add(left, right));
}
public static Ex operator -(Ex rhs)
{
return new Ex(Expression.Negate(rhs));
}
public static Ex operator -(Ex left, Ex right)
{
return new Ex(Expression.Subtract(left, right));
}
public static Ex operator *(Ex left, Ex right)
{
return new Ex(Expression.Multiply(left, right));
}
public static Ex operator /(Ex left, Ex right)
{
return new Ex(Expression.Divide(left, right));
}
}
所以这是我想要做的事情:
{ ...
Ex x = "x";
Ex y = 10.0;
Ex z = x + y;
LambdaExpression lambda = BuildLambda(z);
Func<double,double> f = (Func<double,double>)lambda.Compile();
// f(5) = 15
}
但是如何正确遍历树并构建我的lambda(或委托)呢?
LambdaExpression BuildLambda(Expression e)
{
ConstantExpression cex = e as ConstantExpression;
if(cex != null)
{
return Expression.Lambda<Func<double>>( cex );
}
ParameterExpression pex = e as ParameterExpression;
if (pex != null)
{
Func<Expression, Expression> f = (x) => x;
Expression body = f(pex);
return Expression.Lambda<Func<double, double>>( body , pex);
}
BinaryExpression bex = e as BinaryExpression;
if (bex != null)
{
LambdaExpression left = GetLambda(bex.Left);
LambdaExpression rght = GetLambda(bex.Right);
// Now what?
}
return null;
}
我已经尝试了几种方法将二进制表达式 bex 转换为 lambda,但到目前为止都没有成功。我希望能得到一些建议和指针。请注意,操作数可能是其他表达式对象,并且只有在树的叶子节点上它们才会是 ParameterExpression 或 ConstantExpression。
谢谢。
Ex x = "x"
运行得很好。通过Ex x = "x"; Ex y = 10.0; Ex z = x + y; Expression<Func<double, double>> lambda = Expression.Lambda<Func<double, double>>((Expression) z, (ParameterExpression) (Expression) x); Func<double, double> f3 = (Func<double, double>)lambda.Compile(); double result = f3(5); // result = 15
解决了创建代理的问题。所以非常感谢。诀窍就是去做它,让编译器解决细节问题。 - John Alexiou