11
11
//
12
12
13
13
using System ;
14
+ using System . Collections . Concurrent ;
14
15
using System . Collections . Generic ;
15
16
using System . ComponentModel ;
16
17
using System . Linq ;
@@ -181,7 +182,7 @@ public static bool IsNumericType(this Type type)
181
182
}
182
183
return false ;
183
184
}
184
-
185
+
185
186
public static bool IsIntegerType ( this Type type )
186
187
{
187
188
if ( type == null ) return false ;
@@ -233,7 +234,7 @@ public static Type GetTypeWithGenericInterfaceOf(this Type type, Type genericInt
233
234
{
234
235
foreach ( var t in type . GetTypeInterfaces ( ) )
235
236
{
236
- if ( t . IsGeneric ( ) && t . GetGenericTypeDefinition ( ) == genericInterfaceType )
237
+ if ( t . IsGeneric ( ) && t . GetGenericTypeDefinition ( ) == genericInterfaceType )
237
238
return t ;
238
239
}
239
240
@@ -399,7 +400,7 @@ public static EmptyCtorDelegate GetConstructorMethodToCache(Type type)
399
400
{
400
401
var genericArgs = type . GetGenericArguments ( ) ;
401
402
var typeArgs = new Type [ genericArgs . Length ] ;
402
- for ( var i = 0 ; i < genericArgs . Length ; i ++ )
403
+ for ( var i = 0 ; i < genericArgs . Length ; i ++ )
403
404
typeArgs [ i ] = typeof ( object ) ;
404
405
405
406
var realizedType = type . MakeGenericType ( typeArgs ) ;
@@ -488,7 +489,7 @@ public static object CreateInstance(this Type type)
488
489
}
489
490
490
491
public static T CreateInstance < T > ( this Type type )
491
- {
492
+ {
492
493
var ctorFn = GetConstructorMethod ( type ) ;
493
494
return ( T ) ctorFn ( ) ;
494
495
}
@@ -549,9 +550,9 @@ public static PropertyInfo[] GetSerializableProperties(this Type type)
549
550
if ( type . IsDto ( ) )
550
551
{
551
552
return ! Env . IsMono
552
- ? publicReadableProperties . Where ( attr =>
553
+ ? publicReadableProperties . Where ( attr =>
553
554
attr . IsDefined ( typeof ( DataMemberAttribute ) , false ) ) . ToArray ( )
554
- : publicReadableProperties . Where ( attr =>
555
+ : publicReadableProperties . Where ( attr =>
555
556
attr . AllAttributes ( ) . Any ( x => x . GetType ( ) . Name == DataMember ) ) . ToArray ( ) ;
556
557
}
557
558
@@ -561,18 +562,19 @@ public static PropertyInfo[] GetSerializableProperties(this Type type)
561
562
562
563
public static FieldInfo [ ] GetSerializableFields ( this Type type )
563
564
{
564
- if ( type . IsDto ( ) ) {
565
+ if ( type . IsDto ( ) )
566
+ {
565
567
return new FieldInfo [ 0 ] ;
566
568
}
567
-
569
+
568
570
var publicFields = type . GetPublicFields ( ) ;
569
571
570
572
// else return those properties that are not decorated with IgnoreDataMember
571
573
return publicFields . Where ( prop => prop . AllAttributes ( ) . All ( attr => attr . GetType ( ) . Name != IgnoreDataMember ) ) . ToArray ( ) ;
572
574
}
573
-
574
- #if ! SILVERLIGHT && ! MONOTOUCH
575
- static readonly Dictionary < Type , FastMember . TypeAccessor > typeAccessorMap
575
+
576
+ #if ! SILVERLIGHT && ! MONOTOUCH
577
+ static readonly Dictionary < Type , FastMember . TypeAccessor > typeAccessorMap
576
578
= new Dictionary < Type , FastMember . TypeAccessor > ( ) ;
577
579
#endif
578
580
@@ -626,7 +628,8 @@ public static DataContractAttribute GetWeakDataContract(this Type type)
626
628
typeAccessorMap [ attrType ] = accessor = FastMember . TypeAccessor . Create ( attr . GetType ( ) ) ;
627
629
}
628
630
629
- return new DataContractAttribute {
631
+ return new DataContractAttribute
632
+ {
630
633
Name = ( string ) accessor [ attr , "Name" ] ,
631
634
Namespace = ( string ) accessor [ attr , "Namespace" ] ,
632
635
} ;
@@ -648,8 +651,9 @@ public static DataMemberAttribute GetWeakDataMember(this PropertyInfo pi)
648
651
typeAccessorMap [ attrType ] = accessor = FastMember . TypeAccessor . Create ( attr . GetType ( ) ) ;
649
652
}
650
653
651
- var newAttr = new DataMemberAttribute {
652
- Name = ( string ) accessor [ attr , "Name" ] ,
654
+ var newAttr = new DataMemberAttribute
655
+ {
656
+ Name = ( string ) accessor [ attr , "Name" ] ,
653
657
EmitDefaultValue = ( bool ) accessor [ attr , "EmitDefaultValue" ] ,
654
658
IsRequired = ( bool ) accessor [ attr , "IsRequired" ] ,
655
659
} ;
@@ -929,12 +933,97 @@ public static PropertyInfo[] AllProperties(this Type type)
929
933
#endif
930
934
}
931
935
936
+ static readonly Dictionary < string , List < Attribute > > propertyAttributesMap
937
+ = new Dictionary < string , List < Attribute > > ( ) ;
938
+
939
+ internal static string UniqueKey ( this PropertyInfo pi )
940
+ {
941
+ if ( pi . DeclaringType == null )
942
+ throw new ArgumentException ( "Property '{0}' has no DeclaringType" . Fmt ( pi . Name ) ) ;
943
+
944
+ return pi . DeclaringType . Namespace + "." + pi . DeclaringType . Name + "." + pi . Name ;
945
+ }
946
+
947
+ public static void AddAttributes ( this Type type , params Attribute [ ] attrs )
948
+ {
949
+ #if NETFX_CORE || SILVERLIGHT
950
+ throw new NotSupportedException ( "Adding Attributes at runtime is not supported on this platform" ) ;
951
+ #else
952
+ TypeDescriptor . AddAttributes ( type , attrs ) ;
953
+ #endif
954
+ }
955
+
956
+ /// <summary>
957
+ /// Add a Property attribute at runtime.
958
+ /// <para>Not threadsafe, should only add attributes on Startup.</para>
959
+ /// </summary>
960
+ public static void AddAttributes ( this PropertyInfo propertyInfo , params Attribute [ ] attrs )
961
+ {
962
+ List < Attribute > propertyAttrs ;
963
+ var key = propertyInfo . UniqueKey ( ) ;
964
+ if ( ! propertyAttributesMap . TryGetValue ( key , out propertyAttrs ) )
965
+ {
966
+ propertyAttributesMap [ key ] = propertyAttrs = new List < Attribute > ( ) ;
967
+ }
968
+
969
+ propertyAttrs . AddRange ( attrs ) ;
970
+ }
971
+
972
+ /// <summary>
973
+ /// Add a Property attribute at runtime.
974
+ /// <para>Not threadsafe, should only add attributes on Startup.</para>
975
+ /// </summary>
976
+ public static void ReplaceAttribute ( this PropertyInfo propertyInfo , Attribute attr )
977
+ {
978
+ var key = propertyInfo . UniqueKey ( ) ;
979
+
980
+ List < Attribute > propertyAttrs ;
981
+ if ( ! propertyAttributesMap . TryGetValue ( key , out propertyAttrs ) )
982
+ {
983
+ propertyAttributesMap [ key ] = propertyAttrs = new List < Attribute > ( ) ;
984
+ }
985
+
986
+ propertyAttrs . RemoveAll ( x => x . GetType ( ) == attr . GetType ( ) ) ;
987
+
988
+ propertyAttrs . Add ( attr ) ;
989
+ }
990
+
991
+ public static List < TAttr > GetAttributes < TAttr > ( this PropertyInfo propertyInfo )
992
+ {
993
+ List < Attribute > propertyAttrs ;
994
+ return ! propertyAttributesMap . TryGetValue ( propertyInfo . UniqueKey ( ) , out propertyAttrs )
995
+ ? new List < TAttr > ( )
996
+ : propertyAttrs . OfType < TAttr > ( ) . ToList ( ) ;
997
+ }
998
+
999
+ public static List < Attribute > GetAttributes ( this PropertyInfo propertyInfo )
1000
+ {
1001
+ List < Attribute > propertyAttrs ;
1002
+ return ! propertyAttributesMap . TryGetValue ( propertyInfo . UniqueKey ( ) , out propertyAttrs )
1003
+ ? new List < Attribute > ( )
1004
+ : propertyAttrs . ToList ( ) ;
1005
+ }
1006
+
1007
+ public static List < Attribute > GetAttributes ( this PropertyInfo propertyInfo , Type attrType )
1008
+ {
1009
+ List < Attribute > propertyAttrs ;
1010
+ return ! propertyAttributesMap . TryGetValue ( propertyInfo . UniqueKey ( ) , out propertyAttrs )
1011
+ ? new List < Attribute > ( )
1012
+ : propertyAttrs . Where ( x => x . GetType ( ) == attrType ) . ToList ( ) ;
1013
+ }
1014
+
932
1015
public static object [ ] AllAttributes ( this PropertyInfo propertyInfo )
933
1016
{
934
1017
#if NETFX_CORE
935
1018
return propertyInfo . GetCustomAttributes ( true ) . ToArray ( ) ;
936
1019
#else
937
- return propertyInfo . GetCustomAttributes ( true ) ;
1020
+ var attrs = propertyInfo . GetCustomAttributes ( true ) ;
1021
+ var runtimeAttrs = propertyInfo . GetAttributes ( ) ;
1022
+ if ( runtimeAttrs . Count == 0 )
1023
+ return attrs ;
1024
+
1025
+ runtimeAttrs . AddRange ( attrs . Cast < Attribute > ( ) ) ;
1026
+ return runtimeAttrs . Cast < object > ( ) . ToArray ( ) ;
938
1027
#endif
939
1028
}
940
1029
@@ -943,7 +1032,13 @@ public static object[] AllAttributes(this PropertyInfo propertyInfo, Type attrTy
943
1032
#if NETFX_CORE
944
1033
return propertyInfo . GetCustomAttributes ( true ) . Where ( x => x . GetType ( ) == attrType ) . ToArray ( ) ;
945
1034
#else
946
- return propertyInfo . GetCustomAttributes ( attrType , true ) ;
1035
+ var attrs = propertyInfo . GetCustomAttributes ( attrType , true ) ;
1036
+ var runtimeAttrs = propertyInfo . GetAttributes ( attrType ) ;
1037
+ if ( runtimeAttrs . Count == 0 )
1038
+ return attrs ;
1039
+
1040
+ runtimeAttrs . AddRange ( attrs . Cast < Attribute > ( ) ) ;
1041
+ return runtimeAttrs . Cast < object > ( ) . ToArray ( ) ;
947
1042
#endif
948
1043
}
949
1044
@@ -1020,46 +1115,40 @@ public static TAttr[] AllAttributes<TAttr>(this PropertyInfo pi)
1020
1115
return pi . AllAttributes ( typeof ( TAttr ) ) . Cast < TAttr > ( ) . ToArray ( ) ;
1021
1116
}
1022
1117
1023
- public static TAttr [ ] AllAttributes < TAttr > ( this Type type , bool inherit = true )
1118
+ public static TAttr [ ] AllAttributes < TAttr > ( this Type type )
1024
1119
{
1025
1120
#if NETFX_CORE
1026
- return type . GetTypeInfo ( ) . GetCustomAttributes < T > ( inherit ) . ToArray ( ) ;
1121
+ return type . GetTypeInfo ( ) . GetCustomAttributes < T > ( true ) . ToArray ( ) ;
1027
1122
#elif SILVERLIGHT
1028
1123
return type . GetCustomAttributes ( typeof ( TAttr ) , true ) . Cast < TAttr > ( ) . ToArray ( ) ;
1029
1124
#else
1030
- return type . GetCustomAttributes ( inherit ) . OfType < TAttr > ( ) . ToArray ( ) ;
1125
+ return TypeDescriptor . GetAttributes ( type ) . OfType < TAttr > ( ) . ToArray ( ) ;
1031
1126
#endif
1032
1127
}
1033
1128
1034
- public static TAttr FirstAttribute < TAttr > ( this Type type , bool inherit = true )
1129
+ public static TAttr FirstAttribute < TAttr > ( this Type type )
1035
1130
{
1036
1131
#if NETFX_CORE
1037
- return ( TAttr ) type . GetTypeInfo ( ) . GetCustomAttributes ( typeof ( TAttr ) , inherit )
1132
+ return ( TAttr ) type . GetTypeInfo ( ) . GetCustomAttributes ( typeof ( TAttr ) , true )
1038
1133
. FirstOrDefault ( ) ;
1039
1134
#elif SILVERLIGHT
1040
- return ( TAttr ) type . GetCustomAttributes ( typeof ( TAttr ) , inherit )
1135
+ return ( TAttr ) type . GetCustomAttributes ( typeof ( TAttr ) , true )
1041
1136
. FirstOrDefault ( ) ;
1042
1137
#else
1043
1138
return TypeDescriptor . GetAttributes ( type ) . OfType < TAttr > ( ) . FirstOrDefault ( ) ;
1044
1139
#endif
1045
1140
}
1046
-
1047
- public static TAttribute FirstAttribute < TAttribute > ( this PropertyInfo propertyInfo )
1048
- {
1049
- return propertyInfo . FirstAttribute < TAttribute > ( true ) ;
1050
- }
1051
1141
1052
- public static TAttribute FirstAttribute < TAttribute > ( this PropertyInfo propertyInfo , bool inherit )
1142
+ public static TAttribute FirstAttribute < TAttribute > ( this PropertyInfo propertyInfo )
1053
1143
{
1054
1144
#if NETFX_CORE
1055
1145
var attrs = propertyInfo . GetCustomAttributes < TAttribute > ( inherit ) ;
1056
1146
return ( TAttribute ) ( attrs . Count ( ) > 0 ? attrs . ElementAt ( 0 ) : null ) ;
1057
- #else
1058
- var attrs = propertyInfo . GetCustomAttributes ( typeof ( TAttribute ) , inherit ) ;
1059
- return ( TAttribute ) ( attrs . Length > 0 ? attrs [ 0 ] : null ) ;
1147
+ #else
1148
+ return propertyInfo . AllAttributes < TAttribute > ( ) . FirstOrDefault ( ) ;
1060
1149
#endif
1061
1150
}
1062
-
1151
+
1063
1152
public static Type FirstGenericTypeDefinition ( this Type type )
1064
1153
{
1065
1154
while ( type != null )
@@ -1132,7 +1221,7 @@ public static FieldInfo GetPublicStaticField(this Type type, string fieldName)
1132
1221
#endif
1133
1222
}
1134
1223
1135
- public static Delegate MakeDelegate ( this MethodInfo mi , Type delegateType , bool throwOnBindFailure = true )
1224
+ public static Delegate MakeDelegate ( this MethodInfo mi , Type delegateType , bool throwOnBindFailure = true )
1136
1225
{
1137
1226
#if NETFX_CORE
1138
1227
return mi . CreateDelegate ( delegateType ) ;
@@ -1167,7 +1256,7 @@ public static bool AssignableFrom(this Type type, Type fromType)
1167
1256
return type . IsAssignableFrom ( fromType ) ;
1168
1257
#endif
1169
1258
}
1170
-
1259
+
1171
1260
public static bool IsStandardClass ( this Type type )
1172
1261
{
1173
1262
#if NETFX_CORE
@@ -1240,7 +1329,7 @@ public static bool InstanceOfType(this Type type, object instance)
1240
1329
return type . IsInstanceOfType ( instance ) ;
1241
1330
#endif
1242
1331
}
1243
-
1332
+
1244
1333
public static bool IsClass ( this Type type )
1245
1334
{
1246
1335
#if NETFX_CORE
@@ -1264,7 +1353,7 @@ public static bool IsEnumFlags(this Type type)
1264
1353
#if NETFX_CORE
1265
1354
return type . GetTypeInfo ( ) . IsEnum && type . FirstAttribute < FlagsAttribute > ( false ) != null ;
1266
1355
#else
1267
- return type . IsEnum && type . FirstAttribute < FlagsAttribute > ( false ) != null ;
1356
+ return type . IsEnum && type . FirstAttribute < FlagsAttribute > ( ) != null ;
1268
1357
#endif
1269
1358
}
1270
1359
@@ -1306,8 +1395,8 @@ public static List<U> ConvertAll<T, U>(this List<T> list, Func<T, U> converter)
1306
1395
return result ;
1307
1396
}
1308
1397
#endif
1309
-
1310
-
1398
+
1399
+
1311
1400
}
1312
1401
1313
1402
}
0 commit comments