/// <summary> /// Combines the first expression with the second using the specified merge function. /// </summary> static Expression <T> Compose <T>(this Expression <T> first, Expression <T> second, Func <Expression, Expression, Expression> merge) { // zip parameters (map from parameters of second to parameters of first) var map = first.Parameters .Select((f, i) => new { f, s = second.Parameters[i] }) .ToDictionary(p => p.s, p => p.f); // replace parameters in the second lambda expression with the parameters in the first var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body); // create a merged lambda expression with parameters from the first expression return(Expression.Lambda <T>(merge(first.Body, secondBody), first.Parameters)); }
public static Expression <T> Compose <T> (this Expression <T> first, Expression <T> second, Func <Expression, Expression, Expression> merge) { Expression expression = ParameterRebinder.ReplaceParameters( first.Parameters.Zip( second.Parameters, (f, s) => new { First = f, Second = s }).ToDictionary(p => p.Second, p => p.First), second.Body); return(Expression.Lambda <T> (merge(first.Body, expression), first.Parameters)); }
internal static Expression <T> Compose <T>(this Expression <T> first, Expression <T> second, Func <Expression, Expression, Expression> merge) { // build parameter map (from parameters of second to parameters of first) var map = first.Parameters .Select((f, i) => new { f, s = second.Parameters[i] }) .ToDictionary(p => p.s, p => p.f); // replace parameters in the second lambda expression with parameters from // the first var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body); // apply composition of lambda expression bodies to parameters from // the first expression return(Expression.Lambda <T>(merge(first.Body, secondBody), first.Parameters)); }
/// <summary> /// Combines the first expression with the second using the specified merge function. /// </summary> private static Expression <T> Compose <T>( this Expression <T> first, Expression <T> second, Func <Expression, Expression, Expression> merge) { // Zip parameters (map from parameters of second to parameters of first) Dictionary <ParameterExpression, ParameterExpression> map = first.Parameters .Select((x, i) => new { f = x, s = second.Parameters[i] }) .ToDictionary(y => y.s, p => p.f); // Replace parameters in the second lambda expression with the parameters in the first Expression secondBody = ParameterRebinder.ReplaceParameters(map, second.Body); // Create a merged lambda expression with parameters from the first expression return(Expression.Lambda <T>(merge(first.Body, secondBody), first.Parameters)); }
/// <summary> /// 拼接or 条件语句 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static Expression <Func <T, bool> > Or <T>(this Expression <Func <T, bool> > first, Expression <Func <T, bool> > second) { return(ParameterRebinder.Compose(first, second, Expression.Or)); }
internal static Expression ReplaceParameter(this Expression sourceExpression, ParameterExpression replaceParam, ParameterExpression parameter) { ExpressionVisitor rebinder = new ParameterRebinder(replaceParam, parameter); return(rebinder.Visit(sourceExpression)); }