@@ -131,7 +131,7 @@ public static MethodInfo GetInstanceMethod(this Type type, string methodName) =>
131131 public static bool HasAttribute < T > ( this PropertyInfo pi ) => pi . AllAttributes ( ) . Any ( x => x . GetType ( ) == typeof ( T ) ) ;
132132
133133 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
134- public static bool HasAttributeOf < T > ( this PropertyInfo pi ) => pi . AllAttributes ( ) . Any ( x => x is T ) ;
134+ public static bool HasAttributeOf < T > ( this PropertyInfo pi ) => pi . AllAttributesLazy ( ) . Any ( x => x is T ) ;
135135
136136 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
137137 public static bool HasAttribute < T > ( this FieldInfo fi ) => fi . AllAttributes ( ) . Any ( x => x . GetType ( ) == typeof ( T ) ) ;
@@ -145,7 +145,7 @@ public static MethodInfo GetInstanceMethod(this Type type, string methodName) =>
145145 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
146146 public static bool HasAttributeOf < T > ( this MethodInfo mi ) => mi . AllAttributes ( ) . Any ( x => x is T ) ;
147147
148- private static readonly ConcurrentDictionary < Tuple < MemberInfo , Type > , bool > hasAttributeCache = new ConcurrentDictionary < Tuple < MemberInfo , Type > , bool > ( ) ;
148+ private static readonly ConcurrentDictionary < Tuple < MemberInfo , Type > , bool > hasAttributeCache = new ( ) ;
149149 public static bool HasAttributeCached < T > ( this MemberInfo memberInfo )
150150 {
151151 var key = new Tuple < MemberInfo , Type > ( memberInfo , typeof ( T ) ) ;
@@ -200,7 +200,7 @@ public static bool HasAttributeNamed(this Type type, string name)
200200 public static bool HasAttributeNamed ( this PropertyInfo pi , string name )
201201 {
202202 var normalizedAttr = name . Replace ( "Attribute" , "" ) . ToLower ( ) ;
203- return pi . AllAttributes ( ) . Any ( x => x . GetType ( ) . Name . Replace ( "Attribute" , "" ) . ToLower ( ) == normalizedAttr ) ;
203+ return pi . AllAttributesLazy ( ) . Any ( x => x . GetType ( ) . Name . Replace ( "Attribute" , "" ) . ToLower ( ) == normalizedAttr ) ;
204204 }
205205
206206 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -241,11 +241,9 @@ public static PropertyInfo[] AllProperties(this Type type) =>
241241 type . GetProperties ( BindingFlags . Instance | BindingFlags . NonPublic | BindingFlags . Public ) ;
242242
243243 //Should only register Runtime Attributes on StartUp, So using non-ThreadSafe Dictionary is OK
244- static Dictionary < string , List < Attribute > > propertyAttributesMap
245- = new Dictionary < string , List < Attribute > > ( ) ;
244+ static Dictionary < string , List < Attribute > > propertyAttributesMap = new ( ) ;
246245
247- static Dictionary < Type , List < Attribute > > typeAttributesMap
248- = new Dictionary < Type , List < Attribute > > ( ) ;
246+ static Dictionary < Type , List < Attribute > > typeAttributesMap = new ( ) ;
249247
250248 public static void ClearRuntimeAttributes ( )
251249 {
@@ -335,6 +333,20 @@ public static object[] AllAttributes(this PropertyInfo propertyInfo)
335333 return runtimeAttrs . Cast < object > ( ) . ToArray ( ) ;
336334 }
337335
336+ public static IEnumerable < object > AllAttributesLazy ( this PropertyInfo propertyInfo )
337+ {
338+ var attrs = propertyInfo . GetCustomAttributes ( true ) ;
339+ var runtimeAttrs = propertyInfo . GetAttributes ( ) ;
340+ foreach ( var attr in runtimeAttrs )
341+ {
342+ yield return attr ;
343+ }
344+ foreach ( var attr in attrs )
345+ {
346+ yield return attr ;
347+ }
348+ }
349+
338350 public static object [ ] AllAttributes ( this PropertyInfo propertyInfo , Type attrType )
339351 {
340352 var attrs = propertyInfo . GetCustomAttributes ( attrType , true ) ;
@@ -346,6 +358,18 @@ public static object[] AllAttributes(this PropertyInfo propertyInfo, Type attrTy
346358 return runtimeAttrs . Cast < object > ( ) . ToArray ( ) ;
347359 }
348360
361+ public static IEnumerable < object > AllAttributesLazy ( this PropertyInfo propertyInfo , Type attrType )
362+ {
363+ foreach ( var attr in propertyInfo . GetAttributes ( attrType ) )
364+ {
365+ yield return attr ;
366+ }
367+ foreach ( var attr in propertyInfo . GetCustomAttributes ( attrType , true ) )
368+ {
369+ yield return attr ;
370+ }
371+ }
372+
349373 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
350374 public static object [ ] AllAttributes ( this ParameterInfo paramInfo ) => paramInfo . GetCustomAttributes ( true ) ;
351375
@@ -373,6 +397,15 @@ public static object[] AllAttributes(this MemberInfo memberInfo, Type attrType)
373397 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
374398 public static object [ ] AllAttributes ( this Type type ) => type . GetCustomAttributes ( true ) . Union ( type . GetRuntimeAttributes ( ) ) . ToArray ( ) ;
375399
400+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
401+ public static IEnumerable < object > AllAttributesLazy ( this Type type )
402+ {
403+ foreach ( var attr in type . GetRuntimeAttributes ( ) )
404+ yield return attr ;
405+ foreach ( var attr in type . GetCustomAttributes ( true ) )
406+ yield return attr ;
407+ }
408+
376409 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
377410 public static object [ ] AllAttributes ( this Type type , Type attrType ) =>
378411 type . GetCustomAttributes ( attrType , true ) . Union ( type . GetRuntimeAttributes ( attrType ) ) . ToArray ( ) ;
@@ -392,6 +425,9 @@ public static object[] AllAttributes(this Type type, Type attrType) =>
392425 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
393426 public static TAttr [ ] AllAttributes < TAttr > ( this PropertyInfo pi ) => pi . AllAttributes ( typeof ( TAttr ) ) . Cast < TAttr > ( ) . ToArray ( ) ;
394427
428+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
429+ public static IEnumerable < TAttr > AllAttributesLazy < TAttr > ( this PropertyInfo pi ) => pi . AllAttributesLazy ( typeof ( TAttr ) ) . Cast < TAttr > ( ) ;
430+
395431 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
396432 static IEnumerable < T > GetRuntimeAttributes < T > ( this Type type ) => typeAttributesMap . TryGetValue ( type , out var attrs )
397433 ? attrs . OfType < T > ( )
@@ -411,6 +447,19 @@ public static TAttr[] AllAttributes<TAttr>(this Type type)
411447 . ToArray ( ) ;
412448 }
413449
450+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
451+ public static IEnumerable < TAttr > AllAttributesLazy < TAttr > ( this Type type )
452+ {
453+ foreach ( var attr in type . GetCustomAttributes ( typeof ( TAttr ) , true ) . OfType < TAttr > ( ) )
454+ {
455+ yield return attr ;
456+ }
457+ foreach ( var attr in type . GetRuntimeAttributes < TAttr > ( ) )
458+ {
459+ yield return attr ;
460+ }
461+ }
462+
414463 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
415464 public static TAttr FirstAttribute < TAttr > ( this Type type ) where TAttr : class
416465 {
@@ -432,10 +481,8 @@ public static TAttribute FirstAttribute<TAttribute>(this ParameterInfo paramInfo
432481 }
433482
434483 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
435- public static TAttribute FirstAttribute < TAttribute > ( this PropertyInfo propertyInfo )
436- {
437- return propertyInfo . AllAttributes < TAttribute > ( ) . FirstOrDefault ( ) ;
438- }
484+ public static TAttribute FirstAttribute < TAttribute > ( this PropertyInfo propertyInfo ) =>
485+ propertyInfo . AllAttributesLazy < TAttribute > ( ) . FirstOrDefault ( ) ;
439486
440487 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
441488 public static Type FirstGenericTypeDefinition ( this Type type )
0 commit comments