ja7*_*a72 4 c# lambda expression-trees
这可能是一些人所熟悉的.我有一个包装类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));
}
}
Run Code Online (Sandbox Code Playgroud)
所以这就是我想要做的:
{ ...
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
}
Run Code Online (Sandbox Code Playgroud)
但是我如何正确地横向树并建立我的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;
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试了几种方法来将BinaryExpression
bex转换为lambda,到目前为止所有这些都是不成功的.我想要一些建议和指示.请注意,操作的操作数可能是其他表达式对象,并且只在树的叶子上它们将是ParameterExpression
或ConstantExpression
.
谢谢.
您可以在调用转换运算符时创建表达式树:
public class Ex
{
private readonly Expression expr;
public Ex(Expression expr)
{
this.expr= expr;
}
public Expression Expression
{
get { return this.expr; }
}
public static Ex operator +(Ex left, Ex right)
{
return new Ex(Expression.Add(left.expr, right.expr));
} ? ?
// etc.
}
Run Code Online (Sandbox Code Playgroud)
在每个步骤中,您Expression
从Ex
实例中"解压缩" ,应用Expression.*
方法,并将结果包装在新Ex
实例中.
最后,您所要做的就是Expression
从最终Ex
实例中提取:
Ex x = new Ex(Expression.Parameter(typeof(double), "x"));
Ex y = new Ex(Expression.Constant(10.0, typeof(double)));
Ex z = x + y;
Expression<Func<double, double>> result =
Expression.Lambda<Func<double, double>>(z.Expression, x.Expression);
Run Code Online (Sandbox Code Playgroud)
请注意,C#编译器提供了为您创建表达式树的功能:
Expression<Func<double, double>> result = x => x + 10.0;
Run Code Online (Sandbox Code Playgroud)
创建与上面的代码完全相同的表达式树.
归档时间: |
|
查看次数: |
4618 次 |
最近记录: |