10
10
// Licensed under the same terms of ServiceStack.
11
11
//
12
12
using System ;
13
+ using System . Collections . Generic ;
13
14
using System . Reflection ;
15
+ using System . Threading ;
14
16
using ServiceStack . Text ;
15
17
#if ! XBOX
16
18
using System . Linq . Expressions ;
@@ -20,6 +22,52 @@ namespace ServiceStack.Reflection
20
22
//Also exists in ServiceStack.Common in ServiceStack.Reflection namespace
21
23
public static class StaticAccessors
22
24
{
25
+ private static Dictionary < string , Func < object , object > > getterFnCache = new Dictionary < string , Func < object , object > > ( ) ;
26
+
27
+ public static Func < object , object > GetFastGetter ( this Type type , string propName )
28
+ {
29
+ var key = $ "{ type . Namespace } .{ type . Name } ::{ propName } ";
30
+ Func < object , object > fn ;
31
+ if ( getterFnCache . TryGetValue ( key , out fn ) )
32
+ return fn ;
33
+
34
+ fn = GetValueGetter ( type . GetProperty ( propName ) ) ;
35
+
36
+ Dictionary < string , Func < object , object > > snapshot , newCache ;
37
+ do
38
+ {
39
+ snapshot = getterFnCache ;
40
+ newCache = new Dictionary < string , Func < object , object > > ( getterFnCache ) { [ key ] = fn } ;
41
+
42
+ } while ( ! ReferenceEquals (
43
+ Interlocked . CompareExchange ( ref getterFnCache , newCache , snapshot ) , snapshot ) ) ;
44
+
45
+ return fn ;
46
+ }
47
+
48
+ private static Dictionary < string , Action < object , object > > setterFnCache = new Dictionary < string , Action < object , object > > ( ) ;
49
+
50
+ public static Action < object , object > GetFastSetter ( this Type type , string propName )
51
+ {
52
+ var key = $ "{ type . Namespace } .{ type . Name } ::{ propName } ";
53
+ Action < object , object > fn ;
54
+ if ( setterFnCache . TryGetValue ( key , out fn ) )
55
+ return fn ;
56
+
57
+ fn = GetValueSetter ( type . GetProperty ( propName ) ) ;
58
+
59
+ Dictionary < string , Action < object , object > > snapshot , newCache ;
60
+ do
61
+ {
62
+ snapshot = setterFnCache ;
63
+ newCache = new Dictionary < string , Action < object , object > > ( setterFnCache ) { [ key ] = fn } ;
64
+
65
+ } while ( ! ReferenceEquals (
66
+ Interlocked . CompareExchange ( ref setterFnCache , newCache , snapshot ) , snapshot ) ) ;
67
+
68
+ return fn ;
69
+ }
70
+
23
71
public static Func < object , object > GetValueGetter ( this PropertyInfo propertyInfo )
24
72
{
25
73
return GetValueGetter ( propertyInfo , propertyInfo . DeclaringType ) ;
0 commit comments