Two code paths build the Dependencies array via a LINQ chain that allocates an OfTypeIterator, a SelectArrayIterator, and the final array per test:
TUnit.Engine/Building/Collectors/AotTestDataCollector.cs:277:
Dependencies = result.Attributes.OfType<DependsOnAttribute>().Select(a => a.ToTestDependency()).ToArray(),
TUnit.Engine/Discovery/ReflectionTestDataCollector.cs:2213:
Dependencies = result.Attributes.OfType<DependsOnAttribute>().Select(static a => a.ToTestDependency()).ToArray(),
Manual loop with a known/upper-bound capacity:
List<TestDependency>? deps = null;
foreach (var attr in result.Attributes)
{
if (attr is DependsOnAttribute dep)
{
(deps ??= new List<TestDependency>()).Add(dep.ToTestDependency());
}
}
var dependencies = deps?.ToArray() ?? Array.Empty<TestDependency>();
For tests with zero DependsOnAttribute (the common case), this avoids both LINQ iterators and the empty-array allocation by returning the shared empty array.
Why hot: Per test built during discovery (both AOT and reflection paths).
TFM: No gating.
Two code paths build the
Dependenciesarray via a LINQ chain that allocates anOfTypeIterator, aSelectArrayIterator, and the final array per test:TUnit.Engine/Building/Collectors/AotTestDataCollector.cs:277:TUnit.Engine/Discovery/ReflectionTestDataCollector.cs:2213:Manual loop with a known/upper-bound capacity:
For tests with zero
DependsOnAttribute(the common case), this avoids both LINQ iterators and the empty-array allocation by returning the shared empty array.Why hot: Per test built during discovery (both AOT and reflection paths).
TFM: No gating.