@@ -253,8 +253,6 @@ private static ICriterion Le(ProjectionInfo property, object value)
253
253
public static object FindValue ( Expression expression )
254
254
{
255
255
object value ;
256
- object [ ] args ;
257
- System . Type type ;
258
256
switch ( expression . NodeType )
259
257
{
260
258
case ExpressionType . Constant :
@@ -272,54 +270,9 @@ public static object FindValue(Expression expression)
272
270
return ( ( PropertyInfo ) memberExpression . Member ) . GetValue ( value ) ;
273
271
}
274
272
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 )
284
- {
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
- }
297
-
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
273
case ExpressionType . Call :
321
274
var methodCallExpression = ( MethodCallExpression ) expression ;
322
- args = new object [ methodCallExpression . Arguments . Count ] ;
275
+ var args = new object [ methodCallExpression . Arguments . Count ] ;
323
276
for ( int i = 0 ; i < args . Length ; i ++ )
324
277
args [ i ] = FindValue ( methodCallExpression . Arguments [ i ] ) ;
325
278
@@ -340,132 +293,34 @@ public static object FindValue(Expression expression)
340
293
341
294
return methodCallExpression . Method . Invoke ( callingObject , args ) ;
342
295
}
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 )
368
- {
369
- return binaryExpression . Method . Invoke ( null , new [ ] { left , right } ) ;
370
- }
371
- else
372
- {
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
- }
418
- }
419
- break ;
420
- case ExpressionType . Conditional :
421
- var conditionalExpression = ( ConditionalExpression ) expression ;
422
- bool condition = ( bool ) FindValue ( conditionalExpression . Test ) ;
423
- if ( condition )
424
- {
425
- return FindValue ( conditionalExpression . IfTrue ) ;
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 )
296
+ case ExpressionType . Convert :
297
+ var unaryExpression = ( UnaryExpression ) expression ;
298
+ value = FindValue ( unaryExpression . Operand ) ;
299
+ var type = Nullable . GetUnderlyingType ( unaryExpression . Type ) ?? unaryExpression . Type ;
300
+ if ( type == typeof ( object ) || value == null )
435
301
{
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 ;
302
+ return value ;
442
303
}
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 )
304
+ else if ( value is IConvertible || unaryExpression . Method != null )
448
305
{
449
- args = new object [ item . Arguments . Count ] ;
450
- for ( int i = 0 ; i < args . Length ; i ++ )
306
+ if ( type != unaryExpression . Operand . Type )
451
307
{
452
- args [ i ] = FindValue ( item . Arguments [ i ] ) ;
308
+ value = unaryExpression . Method != null ? unaryExpression . Method . Invoke ( null , new [ ] { value } ) : Convert . ChangeType ( value , type ) ;
453
309
}
454
310
455
- item . AddMethod . Invoke ( list , args ) ;
311
+ return value ;
456
312
}
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 ) ;
313
+ break ;
466
314
}
467
315
468
- return Expression . Lambda ( expression ) . Compile ( ) . DynamicInvoke ( ) ;
316
+ var valueExpression = Expression . Lambda ( expression )
317
+ #if NETCOREAPP2_0_OR_GREATER || NET47_OR_GREATER || NETSTANDARD2_0_OR_GREATER
318
+ . Compile ( true ) ;
319
+ #else
320
+ . Compile ( ) ; //Concurrent Compile() call causes "Garbage Collector" suspend all threads too often
321
+ #endif
322
+ value = valueExpression . DynamicInvoke ( ) ;
323
+ return value ;
469
324
}
470
325
471
326
/// <summary>
0 commit comments