dotnet/reactive · error · ArgumentNullException
comparer
Error message
comparer
What it means
The comparer-taking Distinct overload throws ArgumentNullException when the IEqualityComparer<TSource> argument is null. A comparer is required to decide element uniqueness; there is no null-comparer fallback in this overload (use the single-argument overload for default equality). The check runs before Create is invoked.
Solutions
- Pass a concrete comparer such as EqualityComparer<TSource>.Default.
- Use the Distinct(source) overload when you want default equality semantics.
- Fix the comparer factory/registration so it never returns null.
Example fix
// before source.Distinct(comparer); // comparer == null // after source.Distinct(comparer ?? EqualityComparer<int>.Default);
Defensive patterns
Strategy: validation
Validate before calling
if (comparer is null) comparer = EqualityComparer<TSource>.Default; var distinct = source.Distinct(comparer);
Type guard
bool HasComparer<T>(IEqualityComparer<T>? c) => c is not null;
Try / catch
try
{
var distinct = source.Distinct(comparer);
}
catch (ArgumentNullException ex) when (ex.ParamName == "comparer")
{
logger.LogError(ex, "Distinct called with null comparer");
var distinct = source.Distinct();
} Prevention
- Default comparer fields to EqualityComparer<T>.Default at declaration.
- Make comparer factories throw instead of returning null on unknown keys.
- Use the single-argument Distinct overload when default equality suffices.
When it happens
Trigger: Calling source.Distinct(null) with a comparer-typed variable that was never assigned, or a comparer factory returning null.
Common situations: DI/config-driven comparer resolution returning null for an unknown key; conditional comparer building that skips assignment; tests passing null to use 'default' behavior incorrectly.
Related errors
- Value cannot be null. (Parameter 'comparer')
- source
- source
- ArgumentNullException(nameof(comparer))
- Value cannot be null. (Parameter 'comparer')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/f4cb910968b7f3c1.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Distinct.cs:24
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> Distinct<TSource>(IAsyncObservable<TSource> source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
return Create(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.Distinct(observer)));
}
public static IAsyncObservable<TSource> Distinct<TSource>(IAsyncObservable<TSource> source, IEqualityComparer<TSource> comparer)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
return Create(
source,
comparer,
static (source, comparer, observer) => source.SubscribeSafeAsync(AsyncObserver.Distinct(observer, comparer)));
}
}
public partial class AsyncObserver
{
public static IAsyncObserver<TSource> Distinct<TSource>(IAsyncObserver<TSource> observer)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
return Distinct(observer, EqualityComparer<TSource>.Default);
}
View on GitHub (pinned to 94b5d5ab91)