<PackageReference Include="NUnit" Version="4.3.0" />

MethodInfoCache

static class MethodInfoCache
Caches static information for IMethodInfo to reduce re-calculations and memory allocations from reflection.
using NUnit.Framework.Interfaces; using System.Collections.Concurrent; using System.Runtime.CompilerServices; namespace NUnit.Framework.Internal.Builders { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal static class MethodInfoCache { [System.Runtime.CompilerServices.Nullable(0)] internal sealed class TestMethodMetadata { public IParameterInfo[] Parameters { get; } public bool IsAsyncOperation { get; } public bool IsVoidOrUnit { get; } public IRepeatTest[] RepeatTestAttributes { get; } public ITestBuilder[] TestBuilderAttributes { get; } public IWrapTestMethod[] WrapTestMethodAttributes { get; } public ITestAction[] TestActionAttributes { get; } public IWrapSetUpTearDown[] WrapSetupTearDownAttributes { get; } public IApplyToContext[] ApplyToContextAttributes { get; } public TestMethodMetadata(IMethodInfo method) { Parameters = method.GetParameters(); IsAsyncOperation = AsyncToSyncAdapter.IsAsyncOperation(method.MethodInfo); IsVoidOrUnit = Reflect.IsVoidOrUnit(method.ReturnType.Type); RepeatTestAttributes = method.GetCustomAttributes<IRepeatTest>(true); WrapTestMethodAttributes = method.GetCustomAttributes<IWrapTestMethod>(true); WrapSetupTearDownAttributes = method.GetCustomAttributes<IWrapSetUpTearDown>(true); ApplyToContextAttributes = method.GetCustomAttributes<IApplyToContext>(true); TestBuilderAttributes = method.GetCustomAttributes<ITestBuilder>(false); TestActionAttributes = method.GetCustomAttributes<ITestAction>(false); } } private static readonly ConcurrentDictionary<IMethodInfo, TestMethodMetadata> MethodMetadataCache = new ConcurrentDictionary<IMethodInfo, TestMethodMetadata>(); internal static TestMethodMetadata Get(IMethodInfo method) { return MethodMetadataCache.GetOrAdd(method, (IMethodInfo m) => new TestMethodMetadata(m)); } } }