@@ -20,8 +20,8 @@ public static class Reflection
20
20
private const bool ShouldInheritAttributes = false ;
21
21
22
22
private static readonly ConcurrentDictionary < Type , ConstructorInfo > TypesWithOneConstructorCache = new ConcurrentDictionary < Type , ConstructorInfo > ( ) ;
23
- private static readonly ConcurrentDictionary < Type , object > TypeAttributesCache = new ConcurrentDictionary < Type , object > ( ) ;
24
- private static readonly ConcurrentDictionary < Type , object > MethodAttributesCache = new ConcurrentDictionary < Type , object > ( ) ;
23
+ private static readonly ConcurrentDictionary < Type , IEnumerable < object > > TypeAttributesCache = new ConcurrentDictionary < Type , IEnumerable < object > > ( ) ;
24
+ private static readonly ConcurrentDictionary < MethodInfo , IEnumerable < object > > MethodAttributesCache = new ConcurrentDictionary < MethodInfo , IEnumerable < object > > ( ) ;
25
25
private static readonly ConcurrentDictionary < Type , string > FriendlyTypeNames = new ConcurrentDictionary < Type , string > ( ) ;
26
26
private static readonly ConcurrentDictionary < Type , string > FullFriendlyTypeNames = new ConcurrentDictionary < Type , string > ( ) ;
27
27
@@ -291,19 +291,10 @@ public static IEnumerable<object> GetCustomAttributes(object obj, bool shouldInh
291
291
{
292
292
var type = obj . GetType ( ) ;
293
293
var attributes = type . GetTypeInfo ( ) . GetCustomAttributes ( shouldInherit ) ;
294
+ UpdateAttributesIfNeeded ( type , attributes , TypeAttributesCache ) ;
294
295
295
- if ( ! HasAnyAttributes ( attributes , TypeAttributesCache ) )
296
- {
297
- return attributes ;
298
- }
299
-
300
- if ( attributes . Length == TypeAttributesCache . Count )
301
- {
302
- return TypeAttributesCache . Values ;
303
- }
304
-
305
- CacheAttributes ( attributes , TypeAttributesCache ) ;
306
- return TypeAttributesCache . Values ;
296
+ return TypeAttributesCache
297
+ . GetOrAdd ( type , _ => attributes ) ;
307
298
}
308
299
309
300
/// <summary>
@@ -315,19 +306,10 @@ public static IEnumerable<object> GetCustomAttributes(object obj, bool shouldInh
315
306
public static IEnumerable < object > GetCustomAttributes ( MethodInfo method , bool shouldInherit = ShouldInheritAttributes )
316
307
{
317
308
var attributes = method . GetCustomAttributes ( shouldInherit ) ;
309
+ UpdateAttributesIfNeeded ( method , attributes , MethodAttributesCache ) ;
318
310
319
- if ( ! HasAnyAttributes ( attributes , MethodAttributesCache ) )
320
- {
321
- return attributes ;
322
- }
323
-
324
- if ( attributes . Length == MethodAttributesCache . Count )
325
- {
326
- return MethodAttributesCache . Values ;
327
- }
328
-
329
- CacheAttributes ( attributes , MethodAttributesCache ) ;
330
- return MethodAttributesCache . Values ;
311
+ return MethodAttributesCache
312
+ . GetOrAdd ( method , _ => attributes ) ;
331
313
}
332
314
333
315
/// <summary>
@@ -757,21 +739,17 @@ private static bool ObjectPropertiesAreDeeplyEqual(
757
739
return result . Success ;
758
740
}
759
741
760
- private static void CacheAttributes ( IEnumerable < object > attributes , ConcurrentDictionary < Type , object > result )
742
+ private static void UpdateAttributesIfNeeded < T > (
743
+ T key ,
744
+ object [ ] attributes ,
745
+ ConcurrentDictionary < T , IEnumerable < object > > result )
761
746
{
762
- foreach ( var attribute in attributes )
747
+ if ( result . ContainsKey ( key ) )
763
748
{
764
- var attributeType = attribute . GetType ( ) ;
765
- if ( ! result . ContainsKey ( attributeType ) )
766
- {
767
- result . TryAdd ( attributeType , attribute ) ;
768
- }
749
+ result . AddOrUpdate ( key , attributes , ( dictKey , oldValue ) => attributes ) ;
769
750
}
770
751
}
771
752
772
- private static bool HasAnyAttributes ( IReadOnlyCollection < object > attributes , ConcurrentDictionary < Type , object > result )
773
- => attributes . Count != 0 || result . Any ( ) ;
774
-
775
753
private static string GetFriendlyTypeName ( Type type , bool useFullName )
776
754
{
777
755
const string anonymousTypePrefix = "<>f__" ;
0 commit comments