{"record":{"id":"4fbf067db95bbfe9","repo":"dotnet/BenchmarkDotNet","slug":"type-name-is-generic-type-definition-use-benchm","errorCode":null,"errorMessage":"{type.Name} is generic type definition, use BenchmarkSwitcher for it","messagePattern":"(.+?) is generic type definition, use BenchmarkSwitcher for it","errorType":"exception","errorClass":"InvalidBenchmarkDeclarationException","httpStatus":null,"severity":"error","filePath":"src/BenchmarkDotNet/Running/BenchmarkConverter.cs","lineNumber":21,"sourceCode":"using BenchmarkDotNet.Configs;\nusing BenchmarkDotNet.Extensions;\nusing BenchmarkDotNet.Filters;\nusing BenchmarkDotNet.Parameters;\nusing BenchmarkDotNet.Reports;\nusing System.Collections;\nusing System.Collections.Immutable;\nusing System.Reflection;\n\nnamespace BenchmarkDotNet.Running\n{\n    public static class BenchmarkConverter\n    {\n        private const BindingFlags AllMethodsFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;\n\n        public static BenchmarkRunInfo TypeToBenchmarks(Type type, IConfig? config = null)\n        {\n            if (type.IsGenericTypeDefinition)\n                throw new InvalidBenchmarkDeclarationException($\"{type.Name} is generic type definition, use BenchmarkSwitcher for it\"); // for \"open generic types\" should be used BenchmarkSwitcher\n\n            // We should check all methods including private to notify users about private methods with the [Benchmark] attribute\n            var benchmarkMethods = GetOrderedBenchmarkMethods(type.GetMethods(AllMethodsFlags));\n\n            return MethodsToBenchmarksWithFullConfig(type, benchmarkMethods, config);\n        }\n\n        public static BenchmarkRunInfo MethodsToBenchmarks(Type containingType, MethodInfo[] benchmarkMethods, IConfig? config = null)\n            => MethodsToBenchmarksWithFullConfig(containingType, GetOrderedBenchmarkMethods(benchmarkMethods), config);\n\n        private static MethodInfo[] GetOrderedBenchmarkMethods(MethodInfo[] methods)\n            => methods\n                .Select(method => (method, attribute: method.ResolveAttribute<BenchmarkAttribute>()))\n                .Where(pair => pair.attribute is not null)\n                .OrderBy(pair => pair.attribute!.SourceCodeFile)\n                .ThenBy(pair => pair.attribute!.SourceCodeLineNumber)\n                .Select(pair => pair.method)\n                .ToArray();","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/dotnet/BenchmarkDotNet/blob/b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3/src/BenchmarkDotNet/Running/BenchmarkConverter.cs#L3-L39","documentation":"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.","triggerScenarios":"Calling BenchmarkConverter.TypeToBenchmarks(typeof(MyBenchmark<>)) where MyBenchmark<> has an unbound type parameter. This check fires before any method inspection occurs.","commonSituations":"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.","solutions":["Use BenchmarkSwitcher to handle generic types: BenchmarkRunner.Run(typeof(MyBenchmark<>).MakeGenericType(typeof(int))) for a concrete type.","Provide concrete type arguments before conversion: typeof(MyBenchmark<>).MakeGenericType(typeof(int)).","Use BenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).RunWithGenericTypes(...) for multiple generic instantiations."],"exampleFix":"// before\nvar benchmarks = BenchmarkConverter.TypeToBenchmarks(typeof(MyBenchmark<>));\n\n// after (concrete type)\nvar benchmarks = BenchmarkConverter.TypeToBenchmarks(typeof(MyBenchmark<>).MakeGenericType(typeof(int)));\n\n// or use BenchmarkSwitcher for multiple instantiations\nBenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).RunAll();","handlingStrategy":"validation","validationCode":"if (type.IsGenericTypeDefinition)\n    throw new InvalidOperationException($\"{type.Name} is open generic; provide type arguments or use BenchmarkSwitcher.\");","typeGuard":"static bool IsClosedType(Type type) => !type.IsGenericTypeDefinition;","tryCatchPattern":null,"preventionTips":["Check type.IsGenericTypeDefinition before calling TypeToBenchmarks.","Use BenchmarkSwitcher for generic benchmark types — it supports providing type arguments.","Make generic benchmark types concrete with MakeGenericType before conversion."],"tags":["benchmark-declaration","generics","benchmark-converter"],"backgroundTag":null,"analyzedSha":"b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3","analyzedAt":"2026-08-13T19:12:24.196Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}