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

  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

posted on 2016-09-23 17:05  KnightY  阅读(90)  评论(0编辑  收藏  举报