public static LambdaExpression Combine(this LambdaExpression outer, LambdaExpression inner) { var invoke = Expression.Invoke(inner, outer.Body); var body = new ExpressionRewriter().AutoInline(invoke); return Expression.Lambda(body, outer.Parameters.ToArray()); }
internal Expression AutoInline(InvocationExpression expression) { this.isLocked = true; if (expression == null) throw new ArgumentNullException("expression"); var lambda = (LambdaExpression) expression.Expression; var childScope = new ExpressionRewriter(this); var lambdaParams = lambda.Parameters; var invokeArgs = expression.Arguments; if (lambdaParams.Count != invokeArgs.Count) throw new InvalidOperationException("Lambda/invoke mismatch"); for (int i = 0; i < lambdaParams.Count; i++) { childScope.Subst(lambdaParams[i], invokeArgs[i]); } return childScope.Apply(lambda.Body); }
ExpressionRewriter(ExpressionRewriter parent) { if (parent == null) throw new ArgumentNullException("parent"); this.subst = new Dictionary<Expression, Expression>(parent.subst); this.inline = parent.inline; }