Skip to content

perf: replace magic-string attribute name matching with type/interface check in ConstructorHelper #6056

Description

@thomhurst

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions