Это может быть знакомо некоторым.У меня есть класс-оболочка 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
}
Но как мне аккуратно пересечь дерево и построить лямбду (или делегаты)
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;
}
Я пытался сделать несколько вещей, чтобы преобразовать BinaryExpression
bex в лямбду, и все они до сих пор были безуспешными.Я хотел бы несколько предложений и указателей.Обратите внимание, что операндами операции могут быть другие объекты выражений, и только на листьях дерева они будут либо ParameterExpression
, либо ConstantExpression
.
Спасибо.