您可以使用下面的輔助功能(一個也許可以給他們一個更好的名字,但是這並不重要):
public static class ExpressionUtils
{
public static Expression<Func<TOuter, TResult>> Bind<TOuter, TInner, TResult>(this Expression<Func<TOuter, TInner>> source, Expression<Func<TInner, TResult>> resultSelector)
{
var body = new ParameterExpressionReplacer { source = resultSelector.Parameters[0], target = source.Body }.Visit(resultSelector.Body);
var lambda = Expression.Lambda<Func<TOuter, TResult>>(body, source.Parameters);
return lambda;
}
public static Expression<Func<TOuter, TResult>> ApplyTo<TInner, TResult, TOuter>(this Expression<Func<TInner, TResult>> source, Expression<Func<TOuter, TInner>> innerSelector)
{
return innerSelector.Bind(source);
}
class ParameterExpressionReplacer : ExpressionVisitor
{
public ParameterExpression source;
public Expression target;
protected override Expression VisitParameter(ParameterExpression node)
{
return node == source ? target : base.VisitParameter(node);
}
}
}
讓我們看看如何樣表達
c.Criteria = x => x.Name.StartsWith("SomeTexts");
可以從兩個不同的部分構建。
如果你有
Expression<Func<Customer, string>> e = x => x.Name;
然後
c.Criteria = e.Bind(x => x.StartsWith("SomeTexts"));
,或者如果你有這樣的而不是
Expression<Func<string, bool>> e = x => x.StartsWith("SomeTexts");
然後
c.Criteria = e.ApplyTo((Customer x) => x.Name);
如果你有兩個表達式,那麼你可以使用這兩個函數中的任何一個,因爲a.Bind(b)
等於b.ApplyTo(a)
。
是'p'表達式>'還是'Func '? –
gmiley
不應該'c.Criteria = x.Name.StartWith(「SomeTexts」);'是'c.Criteria = x => x.Name.StartWith(「SomeTexts」);'? –
@YacoubMassad:你是對的:) – Masoud