• 代码收藏


    收集自网络,方便自己,方便他人

      1 public abstract class ExpressionVisitor
      2 {
      3     protected ExpressionVisitor()
      4     {
      5     }
      6 
      7     protected virtual Expression Visit(Expression exp)
      8     {
      9         if (exp == null)
     10             return exp;
     11         switch (exp.NodeType)
     12         {
     13             case ExpressionType.Negate:
     14             case ExpressionType.NegateChecked:
     15             case ExpressionType.Not:
     16             case ExpressionType.Convert:
     17             case ExpressionType.ConvertChecked:
     18             case ExpressionType.ArrayLength:
     19             case ExpressionType.Quote:
     20             case ExpressionType.TypeAs:
     21                 return this.VisitUnary((UnaryExpression)exp);
     22             case ExpressionType.Add:
     23             case ExpressionType.AddChecked:
     24             case ExpressionType.Subtract:
     25             case ExpressionType.SubtractChecked:
     26             case ExpressionType.Multiply:
     27             case ExpressionType.MultiplyChecked:
     28             case ExpressionType.Divide:
     29             case ExpressionType.Modulo:
     30             case ExpressionType.And:
     31             case ExpressionType.AndAlso:
     32             case ExpressionType.Or:
     33             case ExpressionType.OrElse:
     34             case ExpressionType.LessThan:
     35             case ExpressionType.LessThanOrEqual:
     36             case ExpressionType.GreaterThan:
     37             case ExpressionType.GreaterThanOrEqual:
     38             case ExpressionType.Equal:
     39             case ExpressionType.NotEqual:
     40             case ExpressionType.Coalesce:
     41             case ExpressionType.ArrayIndex:
     42             case ExpressionType.RightShift:
     43             case ExpressionType.LeftShift:
     44             case ExpressionType.ExclusiveOr:
     45                 return this.VisitBinary((BinaryExpression)exp);
     46             case ExpressionType.TypeIs:
     47                 return this.VisitTypeIs((TypeBinaryExpression)exp);
     48             case ExpressionType.Conditional:
     49                 return this.VisitConditional((ConditionalExpression)exp);
     50             case ExpressionType.Constant:
     51                 return this.VisitConstant((ConstantExpression)exp);
     52             case ExpressionType.Parameter:
     53                 return this.VisitParameter((ParameterExpression)exp);
     54             case ExpressionType.MemberAccess:
     55                 return this.VisitMemberAccess((MemberExpression)exp);
     56             case ExpressionType.Call:
     57                 return this.VisitMethodCall((MethodCallExpression)exp);
     58             case ExpressionType.Lambda:
     59                 return this.VisitLambda((LambdaExpression)exp);
     60             case ExpressionType.New:
     61                 return this.VisitNew((NewExpression)exp);
     62             case ExpressionType.NewArrayInit:
     63             case ExpressionType.NewArrayBounds:
     64                 return this.VisitNewArray((NewArrayExpression)exp);
     65             case ExpressionType.Invoke:
     66                 return this.VisitInvocation((InvocationExpression)exp);
     67             case ExpressionType.MemberInit:
     68                 return this.VisitMemberInit((MemberInitExpression)exp);
     69             case ExpressionType.ListInit:
     70                 return this.VisitListInit((ListInitExpression)exp);
     71             default:
     72                 throw new Exception(string.Format("Unhandled expression type: '{0}'", exp.NodeType));
     73         }
     74     }
     75 
     76     protected virtual MemberBinding VisitBinding(MemberBinding binding)
     77     {
     78         switch (binding.BindingType)
     79         {
     80             case MemberBindingType.Assignment:
     81                 return this.VisitMemberAssignment((MemberAssignment)binding);
     82             case MemberBindingType.MemberBinding:
     83                 return this.VisitMemberMemberBinding((MemberMemberBinding)binding);
     84             case MemberBindingType.ListBinding:
     85                 return this.VisitMemberListBinding((MemberListBinding)binding);
     86             default:
     87                 throw new Exception(string.Format("Unhandled binding type '{0}'", binding.BindingType));
     88         }
     89     }
     90 
     91     protected virtual ElementInit VisitElementInitializer(ElementInit initializer)
     92     {
     93         ReadOnlyCollection<Expression> arguments = this.VisitExpressionList(initializer.Arguments);
     94         if (arguments != initializer.Arguments)
     95         {
     96             return Expression.ElementInit(initializer.AddMethod, arguments);
     97         }
     98         return initializer;
     99     }
    100 
    101     protected virtual Expression VisitUnary(UnaryExpression u)
    102     {
    103         Expression operand = this.Visit(u.Operand);
    104         if (operand != u.Operand)
    105         {
    106             return Expression.MakeUnary(u.NodeType, operand, u.Type, u.Method);
    107         }
    108         return u;
    109     }
    110 
    111     protected virtual Expression VisitBinary(BinaryExpression b)
    112     {
    113         Expression left = this.Visit(b.Left);
    114         Expression right = this.Visit(b.Right);
    115         Expression conversion = this.Visit(b.Conversion);
    116         if (left != b.Left || right != b.Right || conversion != b.Conversion)
    117         {
    118             if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null)
    119                 return Expression.Coalesce(left, right, conversion as LambdaExpression);
    120             else
    121                 return Expression.MakeBinary(b.NodeType, left, right, b.IsLiftedToNull, b.Method);
    122         }
    123         return b;
    124     }
    125 
    126     protected virtual Expression VisitTypeIs(TypeBinaryExpression b)
    127     {
    128         Expression expr = this.Visit(b.Expression);
    129         if (expr != b.Expression)
    130         {
    131             return Expression.TypeIs(expr, b.TypeOperand);
    132         }
    133         return b;
    134     }
    135 
    136     protected virtual Expression VisitConstant(ConstantExpression c)
    137     {
    138         return c;
    139     }
    140 
    141     protected virtual Expression VisitConditional(ConditionalExpression c)
    142     {
    143         Expression test = this.Visit(c.Test);
    144         Expression ifTrue = this.Visit(c.IfTrue);
    145         Expression ifFalse = this.Visit(c.IfFalse);
    146         if (test != c.Test || ifTrue != c.IfTrue || ifFalse != c.IfFalse)
    147         {
    148             return Expression.Condition(test, ifTrue, ifFalse);
    149         }
    150         return c;
    151     }
    152 
    153     protected virtual Expression VisitParameter(ParameterExpression p)
    154     {
    155         return p;
    156     }
    157 
    158     protected virtual Expression VisitMemberAccess(MemberExpression m)
    159     {
    160         Expression exp = this.Visit(m.Expression);
    161         if (exp != m.Expression)
    162         {
    163             return Expression.MakeMemberAccess(exp, m.Member);
    164         }
    165         return m;
    166     }
    167 
    168     protected virtual Expression VisitMethodCall(MethodCallExpression m)
    169     {
    170         Expression obj = this.Visit(m.Object);
    171         IEnumerable<Expression> args = this.VisitExpressionList(m.Arguments);
    172         if (obj != m.Object || args != m.Arguments)
    173         {
    174             return Expression.Call(obj, m.Method, args);
    175         }
    176         return m;
    177     }
    178 
    179     protected virtual ReadOnlyCollection<Expression> VisitExpressionList(ReadOnlyCollection<Expression> original)
    180     {
    181         List<Expression> list = null;
    182         for (int i = 0, n = original.Count; i < n; i++)
    183         {
    184             Expression p = this.Visit(original[i]);
    185             if (list != null)
    186             {
    187                 list.Add(p);
    188             }
    189             else if (p != original[i])
    190             {
    191                 list = new List<Expression>(n);
    192                 for (int j = 0; j < i; j++)
    193                 {
    194                     list.Add(original[j]);
    195                 }
    196                 list.Add(p);
    197             }
    198         }
    199         if (list != null)
    200         {
    201             return list.AsReadOnly();
    202         }
    203         return original;
    204     }
    205 
    206     protected virtual MemberAssignment VisitMemberAssignment(MemberAssignment assignment)
    207     {
    208         Expression e = this.Visit(assignment.Expression);
    209         if (e != assignment.Expression)
    210         {
    211             return Expression.Bind(assignment.Member, e);
    212         }
    213         return assignment;
    214     }
    215 
    216     protected virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding)
    217     {
    218         IEnumerable<MemberBinding> bindings = this.VisitBindingList(binding.Bindings);
    219         if (bindings != binding.Bindings)
    220         {
    221             return Expression.MemberBind(binding.Member, bindings);
    222         }
    223         return binding;
    224     }
    225 
    226     protected virtual MemberListBinding VisitMemberListBinding(MemberListBinding binding)
    227     {
    228         IEnumerable<ElementInit> initializers = this.VisitElementInitializerList(binding.Initializers);
    229         if (initializers != binding.Initializers)
    230         {
    231             return Expression.ListBind(binding.Member, initializers);
    232         }
    233         return binding;
    234     }
    235 
    236     protected virtual IEnumerable<MemberBinding> VisitBindingList(ReadOnlyCollection<MemberBinding> original)
    237     {
    238         List<MemberBinding> list = null;
    239         for (int i = 0, n = original.Count; i < n; i++)
    240         {
    241             MemberBinding b = this.VisitBinding(original[i]);
    242             if (list != null)
    243             {
    244                 list.Add(b);
    245             }
    246             else if (b != original[i])
    247             {
    248                 list = new List<MemberBinding>(n);
    249                 for (int j = 0; j < i; j++)
    250                 {
    251                     list.Add(original[j]);
    252                 }
    253                 list.Add(b);
    254             }
    255         }
    256         if (list != null)
    257             return list;
    258         return original;
    259     }
    260 
    261     protected virtual IEnumerable<ElementInit> VisitElementInitializerList(ReadOnlyCollection<ElementInit> original)
    262     {
    263         List<ElementInit> list = null;
    264         for (int i = 0, n = original.Count; i < n; i++)
    265         {
    266             ElementInit init = this.VisitElementInitializer(original[i]);
    267             if (list != null)
    268             {
    269                 list.Add(init);
    270             }
    271             else if (init != original[i])
    272             {
    273                 list = new List<ElementInit>(n);
    274                 for (int j = 0; j < i; j++)
    275                 {
    276                     list.Add(original[j]);
    277                 }
    278                 list.Add(init);
    279             }
    280         }
    281         if (list != null)
    282             return list;
    283         return original;
    284     }
    285 
    286     protected virtual Expression VisitLambda(LambdaExpression lambda)
    287     {
    288         Expression body = this.Visit(lambda.Body);
    289         if (body != lambda.Body)
    290         {
    291             return Expression.Lambda(lambda.Type, body, lambda.Parameters);
    292         }
    293         return lambda;
    294     }
    295 
    296     protected virtual NewExpression VisitNew(NewExpression nex)
    297     {
    298         IEnumerable<Expression> args = this.VisitExpressionList(nex.Arguments);
    299         if (args != nex.Arguments)
    300         {
    301             if (nex.Members != null)
    302                 return Expression.New(nex.Constructor, args, nex.Members);
    303             else
    304                 return Expression.New(nex.Constructor, args);
    305         }
    306         return nex;
    307     }
    308 
    309     protected virtual Expression VisitMemberInit(MemberInitExpression init)
    310     {
    311         NewExpression n = this.VisitNew(init.NewExpression);
    312         IEnumerable<MemberBinding> bindings = this.VisitBindingList(init.Bindings);
    313         if (n != init.NewExpression || bindings != init.Bindings)
    314         {
    315             return Expression.MemberInit(n, bindings);
    316         }
    317         return init;
    318     }
    319 
    320     protected virtual Expression VisitListInit(ListInitExpression init)
    321     {
    322         NewExpression n = this.VisitNew(init.NewExpression);
    323         IEnumerable<ElementInit> initializers = this.VisitElementInitializerList(init.Initializers);
    324         if (n != init.NewExpression || initializers != init.Initializers)
    325         {
    326             return Expression.ListInit(n, initializers);
    327         }
    328         return init;
    329     }
    330 
    331     protected virtual Expression VisitNewArray(NewArrayExpression na)
    332     {
    333         IEnumerable<Expression> exprs = this.VisitExpressionList(na.Expressions);
    334         if (exprs != na.Expressions)
    335         {
    336             if (na.NodeType == ExpressionType.NewArrayInit)
    337             {
    338                 return Expression.NewArrayInit(na.Type.GetElementType(), exprs);
    339             }
    340             else
    341             {
    342                 return Expression.NewArrayBounds(na.Type.GetElementType(), exprs);
    343             }
    344         }
    345         return na;
    346     }
    347 
    348     protected virtual Expression VisitInvocation(InvocationExpression iv)
    349     {
    350         IEnumerable<Expression> args = this.VisitExpressionList(iv.Arguments);
    351         Expression expr = this.Visit(iv.Expression);
    352         if (args != iv.Arguments || expr != iv.Expression)
    353         {
    354             return Expression.Invoke(expr, args);
    355         }
    356         return iv;
    357     }
    358 }
    实现表达式目录树访问器

    转自 https://msdn.microsoft.com/zh-cn/library/bb882521.aspx

  • 相关阅读:
    1225. 岛的周长
    238. Product of Array Except Self除自身以外数组的乘积
    RxJava--Buffer,GroupBy 对比
    RxJava--Buffer,GroupBy 对比
    HDU-2182-Frog
    HDU-2182-Frog
    Linux下必知必会文件和目录
    Linux下必知必会文件和目录
    获取一篇新闻的全部信息
    获取一篇新闻的全部信息
  • 原文地址:https://www.cnblogs.com/knightyj/p/5900756.html
Copyright © 2020-2023  润新知