dotnet/reactive · error · ArgumentNullException
Thrown when comparer is null (ArgumentNullException, param…
Error message
Thrown when comparer is null (ArgumentNullException, param name: comparer)
What it means
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.
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.
Example fix
// before var top = items.MaxBy(x => x.Key, resolver.GetComparer<string>()); // null if unregistered // after var cmp = resolver.GetComparer<string>() ?? Comparer<string>.Default; var top = items.MaxByWithTies(x => x.Key, cmp);
Defensive patterns
Strategy: validation
Validate before calling
if (comparer is null) comparer = Comparer<TKey>.Default; var top = source.MaxBy(keySelector, comparer); // prefer MaxByWithTies
Type guard
static IComparer<TKey> NonNullComparer<TKey>(IComparer<TKey>? c) => c ?? Comparer<TKey>.Default;
Try / catch
try
{
var top = source.MaxBy(keySelector, comparer);
}
catch (ArgumentNullException ex) when (ex.ParamName == "comparer")
{
var top = source.MaxBy(keySelector); // default comparer
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Comparer registries or strategy maps missing an entry for the key type; generic code forwarding an optional comparer parameter left null by the caller.
Related errors
- Thrown when comparer is null (ArgumentNullException, param…
- Thrown when source is null (ArgumentNullException, param…
- Thrown when keySelector is null (ArgumentNullException…
- Thrown when source is null (ArgumentNullException, param…
- Thrown when source is null (ArgumentNullException, param…
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/7ba71b6f5f1353b7.
Report an issue: GitHub.
Appendix: source
Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/MaxBy.cs:48
/// <summary>
/// Returns the elements with the minimum key value by using the specified comparer to compare key values.
/// </summary>
/// <typeparam name="TSource">Source sequence element type.</typeparam>
/// <typeparam name="TKey">Key type.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="keySelector">Key selector used to extract the key for each element in the sequence.</param>
/// <param name="comparer">Comparer used to determine the maximum key value.</param>
/// <returns>List with the elements that share the same maximum key value.</returns>
[Obsolete("Use MaxByWithTies to maintain same behavior with .NET 6 and later", false)]
public static IList<TSource> MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue));
}
#endif
}
}
View on GitHub (pinned to 94b5d5ab91)