dotnet/BenchmarkDotNet · error · InvalidBenchmarkDeclarationException

{type.Name} is generic type definition, use BenchmarkSwitche

Error message

{type.Name} is generic type definition, use BenchmarkSwitcher for it

What it means

Thrown by BenchmarkConverter.TypeToBenchmarks when the provided Type is an open generic type definition (IsGenericTypeDefinition == true). BenchmarkDotNet cannot instantiate open generics directly; it needs concrete type arguments. The BenchmarkSwitcher API supports generic types by allowing users to provide type arguments, but the direct TypeToBenchmarks call does not.

Source

Thrown at src/BenchmarkDotNet/Running/BenchmarkConverter.cs:21

using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Extensions;
using BenchmarkDotNet.Filters;
using BenchmarkDotNet.Parameters;
using BenchmarkDotNet.Reports;
using System.Collections;
using System.Collections.Immutable;
using System.Reflection;

namespace BenchmarkDotNet.Running
{
    public static class BenchmarkConverter
    {
        private const BindingFlags AllMethodsFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

        public static BenchmarkRunInfo TypeToBenchmarks(Type type, IConfig? config = null)
        {
            if (type.IsGenericTypeDefinition)
                throw new InvalidBenchmarkDeclarationException($"{type.Name} is generic type definition, use BenchmarkSwitcher for it"); // for "open generic types" should be used BenchmarkSwitcher

            // We should check all methods including private to notify users about private methods with the [Benchmark] attribute
            var benchmarkMethods = GetOrderedBenchmarkMethods(type.GetMethods(AllMethodsFlags));

            return MethodsToBenchmarksWithFullConfig(type, benchmarkMethods, config);
        }

        public static BenchmarkRunInfo MethodsToBenchmarks(Type containingType, MethodInfo[] benchmarkMethods, IConfig? config = null)
            => MethodsToBenchmarksWithFullConfig(containingType, GetOrderedBenchmarkMethods(benchmarkMethods), config);

        private static MethodInfo[] GetOrderedBenchmarkMethods(MethodInfo[] methods)
            => methods
                .Select(method => (method, attribute: method.ResolveAttribute<BenchmarkAttribute>()))
                .Where(pair => pair.attribute is not null)
                .OrderBy(pair => pair.attribute!.SourceCodeFile)
                .ThenBy(pair => pair.attribute!.SourceCodeLineNumber)
                .Select(pair => pair.method)
                .ToArray();

View on GitHub (pinned to b515068b61)

Solutions

  1. Use BenchmarkSwitcher to handle generic types: BenchmarkRunner.Run(typeof(MyBenchmark<>).MakeGenericType(typeof(int))) for a concrete type.
  2. Provide concrete type arguments before conversion: typeof(MyBenchmark<>).MakeGenericType(typeof(int)).
  3. Use BenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).RunWithGenericTypes(...) for multiple generic instantiations.

Example fix

// before
var benchmarks = BenchmarkConverter.TypeToBenchmarks(typeof(MyBenchmark<>));

// after (concrete type)
var benchmarks = BenchmarkConverter.TypeToBenchmarks(typeof(MyBenchmark<>).MakeGenericType(typeof(int)));

// or use BenchmarkSwitcher for multiple instantiations
BenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).RunAll();
Defensive patterns

Strategy: validation

Validate before calling

if (type.IsGenericTypeDefinition)
    throw new InvalidOperationException($"{type.Name} is open generic; provide type arguments or use BenchmarkSwitcher.");

Type guard

static bool IsClosedType(Type type) => !type.IsGenericTypeDefinition;

Prevention

When it happens

Trigger: Calling BenchmarkConverter.TypeToBenchmarks(typeof(MyBenchmark<>)) where MyBenchmark<> has an unbound type parameter. This check fires before any method inspection occurs.

Common situations: Having a generic benchmark class like public class Benchmarks<T> with [Benchmark] methods and trying to run it via TypeToBenchmarks directly instead of using BenchmarkSwitcher.FromAssembly or BenchmarkSwitcher.TypeWithGenericArguments.

Related errors


AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13). Data as JSON: /api/errors/4fbf067db95bbfe9. Report an issue: GitHub.