1010// Licensed under the same terms of ServiceStack.
1111//
1212using System ;
13+ using System . Collections . Generic ;
1314using System . Reflection ;
15+ using System . Threading ;
1416using ServiceStack . Text ;
1517#if ! XBOX
1618using System . Linq . Expressions ;
@@ -20,6 +22,52 @@ namespace ServiceStack.Reflection
2022 //Also exists in ServiceStack.Common in ServiceStack.Reflection namespace
2123 public static class StaticAccessors
2224 {
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+
2371 public static Func < object , object > GetValueGetter ( this PropertyInfo propertyInfo )
2472 {
2573 return GetValueGetter ( propertyInfo , propertyInfo . DeclaringType ) ;
0 commit comments