Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 9a11551

Browse files
committed
Add Lazy alternatives for prop AllAttributes & change First/Has to use them
1 parent 1e192f3 commit 9a11551

1 file changed

Lines changed: 58 additions & 11 deletions

File tree

src/ServiceStack.Text/PlatformExtensions.cs

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)