dotnet/BenchmarkDotNet · error · InvalidBenchmarkDeclarationException

is generic type definition, use BenchmarkSwitcher for it

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.

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.

Appendix: 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)