/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/HoistingExpressionVisitor.cs

https://bitbucket.org/danipen/mono · C# · 32 lines · 19 code · 8 blank · 5 comment · 0 complexity · 9d2fccf1124ad5da71a9db575742456d MD5 · raw file

  1. namespace System.Web.Mvc.ExpressionUtil {
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq.Expressions;
  5. // This is a visitor which rewrites constant expressions as parameter lookups. It's meant
  6. // to produce an expression which can be cached safely.
  7. internal sealed class HoistingExpressionVisitor<TIn, TOut> : ExpressionVisitor {
  8. private static readonly ParameterExpression _hoistedConstantsParamExpr = Expression.Parameter(typeof(List<object>), "hoistedConstants");
  9. private int _numConstantsProcessed;
  10. // factory will create instance
  11. private HoistingExpressionVisitor() { }
  12. public static Expression<Hoisted<TIn, TOut>> Hoist(Expression<Func<TIn, TOut>> expr) {
  13. // rewrite Expression<Func<TIn, TOut>> as Expression<Hoisted<TIn, TOut>>
  14. var visitor = new HoistingExpressionVisitor<TIn, TOut>();
  15. var rewrittenBodyExpr = visitor.Visit(expr.Body);
  16. var rewrittenLambdaExpr = Expression.Lambda<Hoisted<TIn, TOut>>(rewrittenBodyExpr, expr.Parameters[0], _hoistedConstantsParamExpr);
  17. return rewrittenLambdaExpr;
  18. }
  19. protected override Expression VisitConstant(ConstantExpression node) {
  20. // rewrite the constant expression as (TConst)hoistedConstants[i];
  21. return Expression.Convert(Expression.Property(_hoistedConstantsParamExpr, "Item", Expression.Constant(_numConstantsProcessed++)), node.Type);
  22. }
  23. }
  24. }