1111//
1212using System ;
1313using System . Collections . Generic ;
14+ using System . Linq ;
1415using System . Reflection ;
1516using System . Threading ;
1617using ServiceStack . Text ;
@@ -26,12 +27,16 @@ public static class StaticAccessors
2627
2728 public static Func < object , object > GetFastGetter ( this Type type , string propName )
2829 {
29- var key = $ " { type . Namespace } . { type . Name } :: { propName } " ;
30+ var key = GetTypePropertyKey ( type , propName ) ;
3031 Func < object , object > fn ;
3132 if ( getterFnCache . TryGetValue ( key , out fn ) )
3233 return fn ;
3334
34- fn = GetValueGetter ( type . GetPropertyInfo ( propName ) ) ;
35+ var pi = type . GetPropertyInfo ( propName ) ;
36+ if ( pi == null )
37+ return null ;
38+
39+ fn = GetValueGetter ( pi ) ;
3540
3641 Dictionary < string , Func < object , object > > snapshot , newCache ;
3742 do
@@ -45,16 +50,42 @@ public static Func<object, object> GetFastGetter(this Type type, string propName
4550 return fn ;
4651 }
4752
53+ private static string GetTypePropertyKey ( Type type , string propName )
54+ {
55+ var key = StringBuilderThreadStatic . Allocate ( )
56+ . Append ( $ "{ type . Namespace } .{ type . Name } ::{ propName } ") ;
57+
58+ if ( type . IsGenericType ( ) )
59+ {
60+ key . Append ( "<" ) ;
61+ var i = 0 ;
62+ foreach ( var arg in type . GetGenericArguments ( ) )
63+ {
64+ if ( i ++ > 0 )
65+ key . Append ( "," ) ;
66+
67+ key . Append ( $ "{ arg . Namespace } .{ arg . Name } ") ;
68+ }
69+ key . Append ( ">" ) ;
70+ }
71+
72+ return StringBuilderThreadStatic . ReturnAndFree ( key ) ;
73+ }
74+
4875 private static Dictionary < string , Action < object , object > > setterFnCache = new Dictionary < string , Action < object , object > > ( ) ;
4976
5077 public static Action < object , object > GetFastSetter ( this Type type , string propName )
5178 {
52- var key = $ " { type . Namespace } . { type . Name } :: { propName } " ;
79+ var key = GetTypePropertyKey ( type , propName ) ;
5380 Action < object , object > fn ;
5481 if ( setterFnCache . TryGetValue ( key , out fn ) )
5582 return fn ;
5683
57- fn = GetValueSetter ( type . GetPropertyInfo ( propName ) ) ;
84+ var pi = type . GetPropertyInfo ( propName ) ;
85+ if ( pi == null )
86+ return null ;
87+
88+ fn = GetValueSetter ( pi ) ;
5889
5990 Dictionary < string , Action < object , object > > snapshot , newCache ;
6091 do
@@ -86,7 +117,7 @@ public static Func<object, object> GetValueGetter(this PropertyInfo propertyInfo
86117#else
87118
88119 var instance = Expression . Parameter ( typeof ( object ) , "i" ) ;
89- var convertInstance = Expression . TypeAs ( instance , propertyInfo . DeclaringType ) ;
120+ var convertInstance = Expression . TypeAs ( instance , type ) ;
90121 var property = Expression . Property ( convertInstance , propertyInfo ) ;
91122 var convertProperty = Expression . TypeAs ( property , typeof ( object ) ) ;
92123 return Expression . Lambda < Func < object , object > > ( convertProperty , instance ) . Compile ( ) ;
@@ -129,17 +160,17 @@ public static Func<T, object> GetValueGetter<T>(this FieldInfo fieldInfo)
129160 }
130161
131162#if ! XBOX
132- public static Action < object , object > GetValueSetter ( this PropertyInfo propertyInfo , Type instanceType )
163+ public static Action < object , object > GetValueSetter ( this PropertyInfo propertyInfo )
133164 {
134- return GetValueSetter ( propertyInfo ) ;
165+ return GetValueSetter ( propertyInfo , propertyInfo . DeclaringType ) ;
135166 }
136167
137- public static Action < object , object > GetValueSetter ( this PropertyInfo propertyInfo )
168+ public static Action < object , object > GetValueSetter ( this PropertyInfo propertyInfo , Type instanceType )
138169 {
139170 var instance = Expression . Parameter ( typeof ( object ) , "i" ) ;
140171 var argument = Expression . Parameter ( typeof ( object ) , "a" ) ;
141172
142- var type = ( Expression ) Expression . TypeAs ( instance , propertyInfo . DeclaringType ) ;
173+ var type = ( Expression ) Expression . TypeAs ( instance , instanceType ) ;
143174
144175 var setterCall = Expression . Call (
145176 type ,
0 commit comments