namespace System.Web.Mvc.ExpressionUtil { using System; using System.Collections.Generic; using System.Linq.Expressions; // This is a visitor which rewrites constant expressions as parameter lookups. It's meant // to produce an expression which can be cached safely. internal sealed class HoistingExpressionVisitor : ExpressionVisitor { private static readonly ParameterExpression _hoistedConstantsParamExpr = Expression.Parameter(typeof(List), "hoistedConstants"); private int _numConstantsProcessed; // factory will create instance private HoistingExpressionVisitor() { } public static Expression> Hoist(Expression> expr) { // rewrite Expression> as Expression> var visitor = new HoistingExpressionVisitor(); var rewrittenBodyExpr = visitor.Visit(expr.Body); var rewrittenLambdaExpr = Expression.Lambda>(rewrittenBodyExpr, expr.Parameters[0], _hoistedConstantsParamExpr); return rewrittenLambdaExpr; } protected override Expression VisitConstant(ConstantExpression node) { // rewrite the constant expression as (TConst)hoistedConstants[i]; return Expression.Convert(Expression.Property(_hoistedConstantsParamExpr, "Item", Expression.Constant(_numConstantsProcessed++)), node.Type); } } }