{"record":{"id":"343d0d4d37177a45","repo":"dotnet/BenchmarkDotNet","slug":"the-argument-must-be-an-array-of-primitives","errorCode":null,"errorMessage":"The argument must be an array of primitives","messagePattern":"The argument must be an array of primitives","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/BenchmarkDotNet/Code/ArrayParam.cs","lineNumber":77,"sourceCode":"        /// <summary>\n        /// for types where calling .ToString() will be NOT enough to re-create them in auto-generated source code file\n        /// </summary>\n        /// <param name=\"array\">the array</param>\n        /// <param name=\"toSourceCode\">method which transforms an item of type T to it's C# representation\n        /// example: point => $\"new Point2d({point.X}, {point.Y})\"\n        /// </param>\n        [PublicAPI] public static ArrayParam<T> ForComplexTypes(T[] array, Func<T, string> toSourceCode) => new ArrayParam<T>(array, toSourceCode);\n\n        internal static IParam? FromObject(object array)\n        {\n            var type = array.GetType();\n            if (!type.IsArray)\n                throw new InvalidOperationException(\"The argument must be an array\");\n            var elementType = type.GetElementType();\n            if (elementType == null)\n                throw new InvalidOperationException(\"Failed to determine type of array elements\");\n            if (!SourceCodeHelper.IsCompilationTimeConstant(elementType))\n                throw new InvalidOperationException(\"The argument must be an array of primitives\");\n\n            var arrayParamType = typeof(ArrayParam<>).MakeGenericType(elementType);\n\n            var methodInfo = arrayParamType.GetMethod(nameof(ForPrimitives), BindingFlags.Public | BindingFlags.Static)\n                ?? throw new InvalidOperationException($\"{nameof(ForPrimitives)} not found\");\n            return (IParam?)methodInfo.Invoke(null, [array]);\n        }\n    }\n}","sourceCodeStart":59,"sourceCodeEnd":86,"githubUrl":"https://github.com/dotnet/BenchmarkDotNet/blob/b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3/src/BenchmarkDotNet/Code/ArrayParam.cs#L59-L86","documentation":"The final guard in ArrayParam.FromObject: SourceCodeHelper.IsCompilationTimeConstant must return true for the element type. That helper accepts only primitives (int/long/byte/...), bool, string, char, float, double, decimal, enums, Type, TimeInterval, IntPtr and DateTime. Any other element type (a custom class/struct, a record, etc.) causes it to throw because BDN cannot emit it as a compile-time literal in the generated harness.","triggerScenarios":"Declaring an array argument whose element type is a custom class, struct, record, or any non-primitive/non-enum reference type, and routing it through FromObject (the default path for [Arguments]/[Params] arrays of primitives).","commonSituations":"[Arguments(new[] { new MyStruct(...) })] with a user-defined type, arrays of complex DTOs, or arrays of nullable wrappers.","solutions":["For complex element types use ArrayParam<T>.ForComplexTypes(array, item => $\"new T(...)\") and expose it via a custom IParam, which gives BDN the source-code rendering function.","Decompose the complex type into primitive arrays that BDN can emit.","If the type is actually a primitive-compatible enum/Type, make sure its element Type is the enum/Type itself, not a wrapper.","Avoid passing object[] of mixed complex types; use a dedicated params source with a custom IParam."],"exampleFix":"// before\n[Arguments(new Point[] { new Point(1,2) })]\npublic void B(Point[] pts) { }\n\n// after\npublic void B([ParamsSource(nameof(Pts))] Point[] pts) { /* supply via ArrayParam.ForComplexTypes in an IParam */ }","handlingStrategy":"validation","validationCode":"var elementType = array.GetType().GetElementType();\nif (elementType is null || !SourceCodeHelper.IsCompilationTimeConstant(elementType))\n    return ArrayParam<object>.ForComplexTypes(\n        ((IEnumerable<object>)array).ToArray(),\n        item => item?.ToString() ?? \"null\");\nreturn ArrayParam.FromObject(array);","typeGuard":"static bool ElementIsPrimitive(Array a)\n    => a.GetType().GetElementType() is Type t && SourceCodeHelper.IsCompilationTimeConstant(t);","tryCatchPattern":"try { return ArrayParam.FromObject(obj); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"array of primitives\"))\n{\n    // use ArrayParam<T>.ForComplexTypes with a toSourceCode delegate instead\n}","preventionTips":["Keep [Arguments]/[Params] array elements to primitives, enums, string, or Type.","For complex element types, supply a custom IParam via ArrayParam<T>.ForComplexTypes(array, item => $\"...\").","Decompose complex types into primitive arrays when possible."],"tags":["arguments","params","array","source-codegen","primitives","invalidoperation"],"backgroundTag":null,"analyzedSha":"b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3","analyzedAt":"2026-08-13T19:12:24.196Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}