perf: replace Any+IsAssignableTo predicate with 'is T' in ReflectionExtensions.HasAttribute (original) (raw)
TUnit.Core/Extensions/ReflectionExtensions.cs:64-66, 70-72:
return provider.GetCustomAttributes(inherit) .Any(x => x.GetType().IsAssignableTo(typeof(T)));
The fast path at line 59-62 already uses member.IsDefined(typeof(T), inherit). The fallback at :64 allocates:
- An
object[]fromGetCustomAttributes(inherit) - The
Anyenumerator - A delegate for the predicate
x.GetType()per attribute (boxes returnedRuntimeType)IsAssignableToreflection call per attribute
Inline foreach with is T pattern match:
foreach (var x in provider.GetCustomAttributes(inherit)) { if (x is T) return true; } return false;
is T does a single VTable check, no GetType() boxing.
Same swap applies at :108:
return provider.GetCustomAttributes(typeof(T), inherit).Cast().ToArray();
GetCustomAttributes(typeof(T), inherit) already returns object[] whose runtime element type is T[]. Can use Array.ConvertAll or (T[])(object) array-covariance cast in some cases, avoiding the Cast<T> iterator + ToArray round-trip.
Why hot: Every attribute existence check on hot paths (skip/explicit/category lookups, hook discovery).
TFM: No gating.