private static Expression <T> Compose <T>(this Expression <T> first, Expression <T> second, Func <Expression, Expression, Expression> merge) { var map = first.Parameters .Select((f, i) => new { f, s = second.Parameters[i] }) .ToDictionary(p => p.s, p => p.f); var secondBody = ParameterReBinder.ReplaceParameters(map, second.Body); return(Expression.Lambda <T>(merge(first.Body, secondBody), first.Parameters)); }
/// <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)); }
internal static Expression <T> Compose <T>( this Expression <T> first, Expression <T> second, Func <Expression, Expression, Expression> merge) { Dictionary <ParameterExpression, ParameterExpression> map = first.Parameters .Select((parameter, index) => (parameter, second: second.Parameters[index])) .ToDictionary(p => p.second, p => p.parameter); Expression secondBody = ParameterReBinder.ReplaceParameters(map, second.Body); return(Expression.Lambda <T>(merge(first.Body, secondBody), first.Parameters)); }