我有两个表达方式。
我有一个Expression<Func<Foo, bool>>
我想将源表达式转换为Expression<Func<Bar, bool>>
这样做的逻辑是什么?
我一直试图使用Expression.Convert()
,但我相信我做错了。
答案 0 :(得分:3)
要将Expression<Func<Foo, bool>>
转换为Expression<Func<Bar, bool>>
,您还需要Expression<Func<Bar, Foo>>
来处理转化。
你正在做的只是编写表达式。组合表达式比组合函数稍微复杂一些,其中一个人可以简单地调用另一个将结果作为参数传递。这里我们需要用第一个函数的主体替换第二个函数的所有参数实例:
public static Expression<Func<TFirstParam, TResult>>
Compose<TFirstParam, TIntermediate, TResult>(
this Expression<Func<TFirstParam, TIntermediate>> first,
Expression<Func<TIntermediate, TResult>> second)
{
var param = Expression.Parameter(typeof(TFirstParam), "param");
var newFirst = first.Body.Replace(first.Parameters[0], param);
var newSecond = second.Body.Replace(second.Parameters[0], newFirst);
return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param);
}
这依赖于以下方法将一个表达式的所有实例替换为另一个:
public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
现在我们可以执行以下操作:
Expression<Func<Foo, bool>> predicate = GetPrediate();
Expression<Func<Bar, Foo>> selector = GetSelector();
Expression<Func<Bar, bool>> newPredicate = selector.Compose(predicate);