Repository: dotnet/aspnetcore
File: src/Http/Routing/src/ValidationEndpointFilterFactory.cs (C#)

Code before:
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Http.Metadata;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Http.Validation;

internal static class ValidationEndpointFilterFactory
{
    // A small struct to hold the validatable parameter details to avoid allocating arrays for parameters that don't need validation
    private readonly record struct ValidatableParameterEntry(int Index, IValidatableInfo Parameter, string DisplayName);

    public static EndpointFilterDelegate Create(EndpointFilterFactoryContext context, EndpointFilterDelegate next)
    {
        var parameters = context.MethodInfo.GetParameters();
        var options = context.ApplicationServices.GetService<IOptions<ValidationOptions>>()?.Value;
        if (options is null || options.Resolvers.Count == 0)
        {
            return next;
        }

        var serviceProviderIsService = context.ApplicationServices.GetService<IServiceProviderIsService>();

        // Use a list to only store validatable parameters instead of arrays for all parameters
        var validatableParameters = new List<ValidatableParameterEntry>();

        for (var i = 0; i < parameters.Length; i++)
        {
            // Ignore parameters that are resolved from the DI container.
            if (IsServiceParameter(parameters[i], serviceProviderIsService))
            {
                continue;
            }

            if (options.TryGetValidatableParameterInfo(parameters[i], out var validatableParameter))
            {
                validatableParameters.Add(new ValidatableParameterEntry(
                    i,
                    validatableParameter,
                    GetDisplayName(parameters[i])));
            }
        }

        if (validatableParameters.Count == 0)
        {
            return next;
        }

        return async (context) =>
        {

Review comment (suggestion):
Could avoid this allocation if you wanted for endpoints without any validatable params by using `??= new()` when adding the first item.

Code after:
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Http.Metadata;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Http.Validation;

internal static class ValidationEndpointFilterFactory
{
    // A small struct to hold the validatable parameter details to avoid allocating arrays for parameters that don't need validation
    private readonly record struct ValidatableParameterEntry(int Index, IValidatableInfo Parameter, string DisplayName);

    public static EndpointFilterDelegate Create(EndpointFilterFactoryContext context, EndpointFilterDelegate next)
    {
        var parameters = context.MethodInfo.GetParameters();
        var options = context.ApplicationServices.GetService<IOptions<ValidationOptions>>()?.Value;
        if (options is null || options.Resolvers.Count == 0)
        {
            return next;
        }

        var serviceProviderIsService = context.ApplicationServices.GetService<IServiceProviderIsService>();

        // Use a list to only store validatable parameters instead of arrays for all parameters
        List<ValidatableParameterEntry>? validatableParameters = null;

        for (var i = 0; i < parameters.Length; i++)
        {
            // Ignore parameters that are resolved from the DI container.
            if (IsServiceParameter(parameters[i], serviceProviderIsService))
            {
                continue;
            }

            if (options.TryGetValidatableParameterInfo(parameters[i], out var validatableParameter))
            {
                validatableParameters ??= [];
                validatableParameters.Add(new ValidatableParameterEntry(
                    i,
                    validatableParameter,
                    GetDisplayName(parameters[i])));
            }
        }

        if (validatableParameters is null || validatableParameters.Count == 0)
        {
            return next;
        }

        return async (context) =>