perf: replace magic-string attribute name matching with type/interface check in ConstructorHelper (original) (raw)

TUnit.Engine/Discovery/ConstructorHelper.cs:129, 148 detect required properties via string name comparison:

return properties.Any(p => p.GetCustomAttributes().Any(a => a.GetType().Name == "RequiredAttribute"));

var isRequired = property.GetCustomAttribute<System.Runtime.CompilerServices.RequiredMemberAttribute>() != null || property.GetCustomAttributes().Any(a => a.GetType().Name == "RequiredAttribute");

Each check:

  1. Allocates object[] from GetCustomAttributes()
  2. Allocates an Any iterator + lambda
  3. Calls GetType() per attribute, then string-compares .Name

The "older approach" RequiredAttribute mentioned in the comment likely refers to System.ComponentModel.DataAnnotations.RequiredAttribute (or a TUnit one). Use a real type check:

foreach (var attr in property.GetCustomAttributes()) { if (attr is System.ComponentModel.DataAnnotations.RequiredAttribute) return true; }

(Or whichever RequiredAttribute is meant — confirm with git blame.)

Why hot: Per property per type during reflection-mode construction. Compounds with the GetCustomAttributes() allocation noted in the sibling issue.
TFM: No gating.