@@ -252,180 +252,217 @@ private static ICriterion Le(ProjectionInfo property, object value)
252
252
/// </summary>
253
253
public static object FindValue ( Expression expression )
254
254
{
255
- if ( expression . NodeType == ExpressionType . Constant )
256
- {
257
- var constantExpression = ( ConstantExpression ) expression ;
258
- return constantExpression . Value ;
259
- }
260
- else if ( expression . NodeType == ExpressionType . MemberAccess )
261
- {
262
- var memberExpression = ( MemberExpression ) expression ;
263
- var constantValue = memberExpression . Expression != null ? FindValue ( memberExpression . Expression ) : null ;
264
-
265
- switch ( memberExpression . Member . MemberType )
266
- {
267
- case MemberTypes . Field :
268
- return ( ( FieldInfo ) memberExpression . Member ) . GetValue ( constantValue ) ;
269
- case MemberTypes . Property :
270
- return ( ( PropertyInfo ) memberExpression . Member ) . GetValue ( constantValue ) ;
271
- }
272
- }
273
- else if ( expression . NodeType == ExpressionType . Call )
255
+ object value ;
256
+ object [ ] args ;
257
+ System . Type type ;
258
+ switch ( expression . NodeType )
274
259
{
275
- var methodCallExpression = ( MethodCallExpression ) expression ;
276
- var args = new object [ methodCallExpression . Arguments . Count ] ;
277
- for ( int i = 0 ; i < args . Length ; i ++ )
278
- args [ i ] = FindValue ( methodCallExpression . Arguments [ i ] ) ;
260
+ case ExpressionType . Constant :
261
+ var constantExpression = ( ConstantExpression ) expression ;
262
+ return constantExpression . Value ;
263
+ case ExpressionType . MemberAccess :
264
+ var memberExpression = ( MemberExpression ) expression ;
265
+ value = memberExpression . Expression != null ? FindValue ( memberExpression . Expression ) : null ;
279
266
280
- if ( methodCallExpression . Object == null ) //extension or static method
281
- {
282
- if ( args . Length > 0 && args [ 0 ] != null )
267
+ switch ( memberExpression . Member . MemberType )
283
268
{
284
- return methodCallExpression . Method . Invoke ( args [ 0 ] . GetType ( ) , args ) ;
269
+ case MemberTypes . Field :
270
+ return ( ( FieldInfo ) memberExpression . Member ) . GetValue ( value ) ;
271
+ case MemberTypes . Property :
272
+ return ( ( PropertyInfo ) memberExpression . Member ) . GetValue ( value ) ;
285
273
}
286
- else
274
+ break ;
275
+ case ExpressionType . Convert :
276
+ case ExpressionType . Not :
277
+ case ExpressionType . Negate :
278
+ case ExpressionType . UnaryPlus :
279
+ case ExpressionType . Decrement :
280
+ case ExpressionType . Increment :
281
+ var unaryExpression = ( UnaryExpression ) expression ;
282
+ value = FindValue ( unaryExpression . Operand ) ;
283
+ switch ( expression . NodeType )
287
284
{
288
- return methodCallExpression . Method . Invoke ( methodCallExpression . Method . DeclaringType , args ) ;
289
- }
290
- }
291
- else
292
- {
293
- var callingObject = FindValue ( methodCallExpression . Object ) ;
285
+ case ExpressionType . Convert :
286
+ type = Nullable . GetUnderlyingType ( unaryExpression . Type ) ?? unaryExpression . Type ;
287
+ if ( type == typeof ( object ) || value == null )
288
+ {
289
+ return value ;
290
+ }
291
+ else if ( value is IConvertible || unaryExpression . Method != null )
292
+ {
293
+ if ( type != unaryExpression . Operand . Type )
294
+ {
295
+ value = unaryExpression . Method != null ? unaryExpression . Method . Invoke ( null , new [ ] { value } ) : Convert . ChangeType ( value , type ) ;
296
+ }
294
297
295
- return methodCallExpression . Method . Invoke ( callingObject , args ) ;
296
- }
297
- }
298
- else if ( expression . NodeType == ExpressionType . Convert )
299
- {
300
- var unaryExpression = ( UnaryExpression ) expression ;
301
- var value = FindValue ( unaryExpression . Operand ) ;
302
- var type = Nullable . GetUnderlyingType ( unaryExpression . Type ) ?? unaryExpression . Type ;
298
+ return value ;
299
+ }
300
+ break ;
301
+ case ExpressionType . Not :
302
+ if ( value is bool )
303
+ {
304
+ return ! ( dynamic ) value ;
305
+ }
306
+ else
307
+ {
308
+ return ~ ( dynamic ) value ;
309
+ }
310
+ case ExpressionType . Negate :
311
+ return - ( dynamic ) value ;
312
+ case ExpressionType . UnaryPlus :
313
+ return + ( dynamic ) value ;
314
+ case ExpressionType . Decrement :
315
+ return ( dynamic ) value - 1 ;
316
+ case ExpressionType . Increment :
317
+ return ( dynamic ) value + 1 ;
318
+ }
319
+ break ;
320
+ case ExpressionType . Call :
321
+ var methodCallExpression = ( MethodCallExpression ) expression ;
322
+ args = new object [ methodCallExpression . Arguments . Count ] ;
323
+ for ( int i = 0 ; i < args . Length ; i ++ )
324
+ args [ i ] = FindValue ( methodCallExpression . Arguments [ i ] ) ;
303
325
304
- if ( type == typeof ( object ) || value == null )
305
- {
306
- return value ;
307
- }
308
- else if ( value is IConvertible || unaryExpression . Method != null )
309
- {
310
- if ( type != unaryExpression . Operand . Type )
326
+ if ( methodCallExpression . Object == null ) //extension or static method
311
327
{
312
- value = unaryExpression . Method != null ? unaryExpression . Method . Invoke ( null , new [ ] { value } ) : Convert . ChangeType ( value , type ) ;
328
+ if ( args . Length > 0 && args [ 0 ] != null )
329
+ {
330
+ return methodCallExpression . Method . Invoke ( args [ 0 ] . GetType ( ) , args ) ;
331
+ }
332
+ else
333
+ {
334
+ return methodCallExpression . Method . Invoke ( methodCallExpression . Method . DeclaringType , args ) ;
335
+ }
313
336
}
337
+ else
338
+ {
339
+ var callingObject = FindValue ( methodCallExpression . Object ) ;
314
340
315
- return value ;
316
- }
317
- }
318
- else if ( expression is BinaryExpression binary )
319
- {
320
- dynamic left = FindValue ( binary . Left ) ;
321
- dynamic right = FindValue ( binary . Right ) ;
322
- if ( binary . Method != null )
323
- {
324
- return binary . Method . Invoke ( null , new [ ] { left , right } ) ;
325
- }
326
- else
327
- {
328
- switch ( expression . NodeType )
341
+ return methodCallExpression . Method . Invoke ( callingObject , args ) ;
342
+ }
343
+ case ExpressionType . Multiply :
344
+ case ExpressionType . Divide :
345
+ case ExpressionType . Modulo :
346
+ case ExpressionType . Add :
347
+ case ExpressionType . Subtract :
348
+ case ExpressionType . Power :
349
+ case ExpressionType . AndAlso :
350
+ case ExpressionType . OrElse :
351
+ case ExpressionType . And :
352
+ case ExpressionType . Or :
353
+ case ExpressionType . ExclusiveOr :
354
+ case ExpressionType . Equal :
355
+ case ExpressionType . NotEqual :
356
+ case ExpressionType . LessThan :
357
+ case ExpressionType . LessThanOrEqual :
358
+ case ExpressionType . GreaterThan :
359
+ case ExpressionType . GreaterThanOrEqual :
360
+ case ExpressionType . ArrayIndex :
361
+ case ExpressionType . Coalesce :
362
+ case ExpressionType . LeftShift :
363
+ case ExpressionType . RightShift :
364
+ var binaryExpression = ( BinaryExpression ) expression ;
365
+ dynamic left = FindValue ( binaryExpression . Left ) ;
366
+ dynamic right = FindValue ( binaryExpression . Right ) ;
367
+ if ( binaryExpression . Method != null )
329
368
{
330
- case ExpressionType . Multiply :
331
- return left * right ;
332
- case ExpressionType . Divide :
333
- return left / right ;
334
- case ExpressionType . Modulo :
335
- return left % right ;
336
- case ExpressionType . Add :
337
- return left + right ;
338
- case ExpressionType . Subtract :
339
- return left - right ;
340
- case ExpressionType . Power :
341
- return left ^ right ;
342
- case ExpressionType . AndAlso :
343
- return left && right ;
344
- case ExpressionType . OrElse :
345
- return left || right ;
346
- case ExpressionType . And :
347
- return left & right ;
348
- case ExpressionType . Or :
349
- return left | right ;
350
- case ExpressionType . ExclusiveOr :
351
- return left ^ right ;
352
- case ExpressionType . Equal :
353
- return left == right ;
354
- case ExpressionType . NotEqual :
355
- return left != right ;
356
- case ExpressionType . LessThan :
357
- return left < right ;
358
- case ExpressionType . LessThanOrEqual :
359
- return left <= right ;
360
- case ExpressionType . GreaterThan :
361
- return left > right ;
362
- case ExpressionType . GreaterThanOrEqual :
363
- return left >= right ;
364
- case ExpressionType . ArrayIndex :
365
- return left [ right ] ;
366
- case ExpressionType . Coalesce :
367
- return left ?? right ;
368
- case ExpressionType . LeftShift :
369
- return left << right ;
370
- case ExpressionType . RightShift :
371
- return left >> right ;
369
+ return binaryExpression . Method . Invoke ( null , new [ ] { left , right } ) ;
372
370
}
373
- }
374
- }
375
- else if ( expression . NodeType == ExpressionType . Conditional )
376
- {
377
- var conditionalExpression = ( ConditionalExpression ) expression ;
378
- bool condition = ( bool ) FindValue ( conditionalExpression . Test ) ;
379
- if ( condition )
380
- {
381
- return FindValue ( conditionalExpression . IfTrue ) ;
382
- }
383
- else
384
- {
385
- return FindValue ( conditionalExpression . IfFalse ) ;
386
- }
387
- }
388
- else if ( expression . NodeType == ExpressionType . NewArrayInit )
389
- {
390
- var newArrayExpression = ( NewArrayExpression ) expression ;
391
- var elementType = newArrayExpression . Type . GetElementType ( ) ;
392
- if ( elementType != null )
393
- {
394
- dynamic array = Array . CreateInstance ( elementType , newArrayExpression . Expressions . Count ) ;
395
- for ( int i = 0 ; i < newArrayExpression . Expressions . Count ; i ++ )
371
+ else
396
372
{
397
- array [ i ] = ( dynamic ) FindValue ( newArrayExpression . Expressions [ i ] ) ;
373
+ switch ( expression . NodeType )
374
+ {
375
+ case ExpressionType . Multiply :
376
+ return left * right ;
377
+ case ExpressionType . Divide :
378
+ return left / right ;
379
+ case ExpressionType . Modulo :
380
+ return left % right ;
381
+ case ExpressionType . Add :
382
+ return left + right ;
383
+ case ExpressionType . Subtract :
384
+ return left - right ;
385
+ case ExpressionType . Power :
386
+ return left ^ right ;
387
+ case ExpressionType . AndAlso :
388
+ return left && right ;
389
+ case ExpressionType . OrElse :
390
+ return left || right ;
391
+ case ExpressionType . And :
392
+ return left & right ;
393
+ case ExpressionType . Or :
394
+ return left | right ;
395
+ case ExpressionType . ExclusiveOr :
396
+ return left ^ right ;
397
+ case ExpressionType . Equal :
398
+ return left == right ;
399
+ case ExpressionType . NotEqual :
400
+ return left != right ;
401
+ case ExpressionType . LessThan :
402
+ return left < right ;
403
+ case ExpressionType . LessThanOrEqual :
404
+ return left <= right ;
405
+ case ExpressionType . GreaterThan :
406
+ return left > right ;
407
+ case ExpressionType . GreaterThanOrEqual :
408
+ return left >= right ;
409
+ case ExpressionType . ArrayIndex :
410
+ return left [ right ] ;
411
+ case ExpressionType . Coalesce :
412
+ return left ?? right ;
413
+ case ExpressionType . LeftShift :
414
+ return left << right ;
415
+ case ExpressionType . RightShift :
416
+ return left >> right ;
417
+ }
398
418
}
399
- return array ;
400
- }
401
- }
402
- else if ( expression . NodeType == ExpressionType . ListInit )
403
- {
404
- var listInitExpression = ( ListInitExpression ) expression ;
405
- var list = Activator . CreateInstance ( listInitExpression . Type ) ;
406
- foreach ( var item in listInitExpression . Initializers )
407
- {
408
- var args = new object [ item . Arguments . Count ] ;
409
- for ( int i = 0 ; i < args . Length ; i ++ )
419
+ break ;
420
+ case ExpressionType . Conditional :
421
+ var conditionalExpression = ( ConditionalExpression ) expression ;
422
+ bool condition = ( bool ) FindValue ( conditionalExpression . Test ) ;
423
+ if ( condition )
410
424
{
411
- args [ i ] = FindValue ( item . Arguments [ i ] ) ;
425
+ return FindValue ( conditionalExpression . IfTrue ) ;
412
426
}
427
+ else
428
+ {
429
+ return FindValue ( conditionalExpression . IfFalse ) ;
430
+ }
431
+ case ExpressionType . NewArrayInit :
432
+ var newArrayExpression = ( NewArrayExpression ) expression ;
433
+ type = newArrayExpression . Type . GetElementType ( ) ;
434
+ if ( type != null )
435
+ {
436
+ dynamic array = Array . CreateInstance ( type , newArrayExpression . Expressions . Count ) ;
437
+ for ( int i = 0 ; i < newArrayExpression . Expressions . Count ; i ++ )
438
+ {
439
+ array [ i ] = ( dynamic ) FindValue ( newArrayExpression . Expressions [ i ] ) ;
440
+ }
441
+ return array ;
442
+ }
443
+ break ;
444
+ case ExpressionType . ListInit :
445
+ var listInitExpression = ( ListInitExpression ) expression ;
446
+ var list = Activator . CreateInstance ( listInitExpression . Type ) ;
447
+ foreach ( var item in listInitExpression . Initializers )
448
+ {
449
+ args = new object [ item . Arguments . Count ] ;
450
+ for ( int i = 0 ; i < args . Length ; i ++ )
451
+ {
452
+ args [ i ] = FindValue ( item . Arguments [ i ] ) ;
453
+ }
413
454
414
- item . AddMethod . Invoke ( list , args ) ;
415
- }
416
-
417
- return list ;
418
- }
419
- else if ( expression . NodeType == ExpressionType . New )
420
- {
421
- var newExpression = ( NewExpression ) expression ;
422
- var args = new object [ newExpression . Arguments . Count ] ;
423
- for ( int i = 0 ; i < args . Length ; i ++ )
424
- {
425
- args [ i ] = FindValue ( newExpression . Arguments [ i ] ) ;
426
- }
427
-
428
- return newExpression . Constructor . Invoke ( args ) ;
455
+ item . AddMethod . Invoke ( list , args ) ;
456
+ }
457
+ return list ;
458
+ case ExpressionType . New :
459
+ var newExpression = ( NewExpression ) expression ;
460
+ args = new object [ newExpression . Arguments . Count ] ;
461
+ for ( int i = 0 ; i < args . Length ; i ++ )
462
+ {
463
+ args [ i ] = FindValue ( newExpression . Arguments [ i ] ) ;
464
+ }
465
+ return newExpression . Constructor . Invoke ( args ) ;
429
466
}
430
467
431
468
return Expression . Lambda ( expression ) . Compile ( ) . DynamicInvoke ( ) ;
0 commit comments