{"record":{"id":"7ba71b6f5f1353b7","repo":"dotnet/reactive","slug":"thrown-when-comparer-is-null-argumentnullexception-param-7ba71b","errorCode":null,"errorMessage":"Thrown when comparer is null (ArgumentNullException, param name: comparer)","messagePattern":"Thrown when comparer is null \\(ArgumentNullException, param name: comparer\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Ix.NET/Source/System.Interactive/System/Linq/Operators/MaxBy.cs","lineNumber":48,"sourceCode":"\n        /// <summary>\n        /// Returns the elements with the minimum key value by using the specified comparer to compare key values.\n        /// </summary>\n        /// <typeparam name=\"TSource\">Source sequence element type.</typeparam>\n        /// <typeparam name=\"TKey\">Key type.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"keySelector\">Key selector used to extract the key for each element in the sequence.</param>\n        /// <param name=\"comparer\">Comparer used to determine the maximum key value.</param>\n        /// <returns>List with the elements that share the same maximum key value.</returns>\n        [Obsolete(\"Use MaxByWithTies to maintain same behavior with .NET 6 and later\", false)]\n        public static IList<TSource> MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue));\n        }\n#endif\n    }\n}\n","sourceCodeStart":30,"sourceCodeEnd":55,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Ix.NET/Source/System.Interactive/System/Linq/Operators/MaxBy.cs#L30-L55","documentation":"The comparer-based MaxBy overload requires a non-null IComparer<TKey> to compare extracted keys. Passing null throws ArgumentNullException with paramName 'comparer' immediately, before enumeration. The overload is obsolete in favor of MaxByWithTies.","triggerScenarios":"Calling source.MaxBy(keySelector, null), or passing a comparer obtained from DI/configuration/factory that returned null, e.g. items.MaxBy(x => x.Key, registry.GetComparer<K>()) with an unregistered type.","commonSituations":"Comparer registries or strategy maps missing an entry for the key type; generic code forwarding an optional comparer parameter left null by the caller.","solutions":["Pass Comparer<TKey>.Default when no custom comparison is required.","Default the comparer before the call: comparer ??= Comparer<TKey>.Default;","Fix the comparer source (register it in DI/registry) and consider migrating to MaxByWithTies."],"exampleFix":"// before\nvar top = items.MaxBy(x => x.Key, resolver.GetComparer<string>()); // null if unregistered\n// after\nvar cmp = resolver.GetComparer<string>() ?? Comparer<string>.Default;\nvar top = items.MaxByWithTies(x => x.Key, cmp);","handlingStrategy":"validation","validationCode":"if (comparer is null) comparer = Comparer<TKey>.Default;\nvar top = source.MaxBy(keySelector, comparer); // prefer MaxByWithTies","typeGuard":"static IComparer<TKey> NonNullComparer<TKey>(IComparer<TKey>? c) => c ?? Comparer<TKey>.Default;","tryCatchPattern":"try\n{\n    var top = source.MaxBy(keySelector, comparer);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"comparer\")\n{\n    var top = source.MaxBy(keySelector); // default comparer\n}","preventionTips":["Apply ?? Comparer<TKey>.Default wherever comparers come from configuration or DI","Ensure comparer registries have entries for all key types in use","Migrate obsolete MaxBy(comparer) calls to MaxByWithTies"],"tags":["argumentnull","linq","dotnet","ix-net","comparer","obsolete-api"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}