收集自网络,方便自己,方便他人
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