55// Created: 2009.04.21
66
77using System ;
8+ using System . Collections . Concurrent ;
89using System . Linq ;
910using System . Linq . Expressions ;
1011using System . Reflection ;
@@ -20,7 +21,10 @@ namespace Xtensive.Linq
2021 /// </summary>
2122 public static class ExpressionExtensions
2223 {
23- private static readonly MethodInfo TupleGenericAccessor ;
24+ private static readonly ConcurrentDictionary < Type , MethodInfo > valueAccessors =
25+ new ConcurrentDictionary < Type , MethodInfo > ( ) ;
26+
27+ private static readonly Func < Type , MethodInfo > TupleValueAccessorFactory ;
2428
2529 ///<summary>
2630 /// Makes <see cref="Tuples.Tuple.GetValueOrDefault{T}"/> method call.
@@ -29,15 +33,12 @@ public static class ExpressionExtensions
2933 ///<param name="accessorType">Type of accessor.</param>
3034 ///<param name="index">Tuple field index.</param>
3135 ///<returns><see cref="MethodCallExpression"/></returns>
32- public static MethodCallExpression MakeTupleAccess ( this Expression target , Type accessorType , int index )
33- {
34- return Expression . Call (
36+ public static MethodCallExpression MakeTupleAccess ( this Expression target , Type accessorType , int index ) =>
37+ Expression . Call (
3538 target ,
36- TupleGenericAccessor . MakeGenericMethod ( accessorType ) ,
39+ valueAccessors . GetOrAdd ( accessorType , TupleValueAccessorFactory ) ,
3740 Expression . Constant ( index )
38- ) ;
39- }
40-
41+ ) ;
4142
4243 /// <summary>
4344 /// Makes <c>IsNull</c> condition expression.
@@ -46,41 +47,38 @@ public static MethodCallExpression MakeTupleAccess(this Expression target, Type
4647 /// <param name="ifNull">Result expression if <paramref name="target"/> is <see langword="null" />.</param>
4748 /// <param name="ifNotNull">Result expression if <paramref name="target"/> is not <see langword="null" />.</param>
4849 /// <returns><see cref="ConditionalExpression"/></returns>
49- public static ConditionalExpression MakeIsNullCondition ( this Expression target , Expression ifNull , Expression ifNotNull )
50- {
51- return Expression . Condition (
50+ public static ConditionalExpression MakeIsNullCondition (
51+ this Expression target , Expression ifNull , Expression ifNotNull ) =>
52+ Expression . Condition (
5253 Expression . Equal ( target , Expression . Constant ( null , target . Type ) ) ,
53- ifNull , ifNotNull
54- ) ;
55- }
54+ ifNull ,
55+ ifNotNull
56+ ) ;
5657
5758 /// <summary>
5859 /// Converts expression type to nullable type (for value types).
5960 /// </summary>
6061 /// <param name="expression">The expression.</param>
61- public static Expression LiftToNullable ( this Expression expression )
62- {
63- return expression . Type . IsNullable ( )
64- ? expression
65- : Expression . Convert ( expression , expression . Type . ToNullable ( ) ) ;
66- }
62+ public static Expression LiftToNullable ( this Expression expression ) =>
63+ expression . Type . IsNullable ( )
64+ ? expression
65+ : Expression . Convert ( expression , expression . Type . ToNullable ( ) ) ;
6766
6867 /// <summary>
6968 /// Converts specified <see cref="Expression"/> to <see cref="ExpressionTree"/>.
7069 /// </summary>
7170 /// <param name="expression">The expression to convert.</param>
7271 /// <returns>Expression tree that wraps <paramref name="expression"/>.</returns>
73- public static ExpressionTree ToExpressionTree ( this Expression expression )
74- {
75- return new ExpressionTree ( expression ) ;
76- }
72+ public static ExpressionTree ToExpressionTree ( this Expression expression ) => new ExpressionTree ( expression ) ;
7773
7874
7975 // Type initializer
8076
8177 static ExpressionExtensions ( )
8278 {
83- TupleGenericAccessor = typeof ( Tuple ) . GetMethods ( ) . Single ( mi => mi . Name == WellKnown . Tuple . GetValueOrDefault && mi . IsGenericMethod ) ;
79+ var tupleGenericAccessor = typeof ( Tuple ) . GetMethods ( )
80+ . Single ( mi => mi . Name == WellKnown . Tuple . GetValueOrDefault && mi . IsGenericMethod ) ;
81+ TupleValueAccessorFactory = type => tupleGenericAccessor . MakeGenericMethod ( type ) ;
8482 }
8583 }
8684}
0 commit comments