{"record":{"id":"fb6abff26141b130","repo":"dotnet/reactive","slug":"comparer-distinctuntilchanged","errorCode":null,"errorMessage":"comparer","messagePattern":"comparer","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/DistinctUntilChanged.cs","lineNumber":25,"sourceCode":"\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TSource> DistinctUntilChanged<TSource>(IAsyncObservable<TSource> source)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n\n            return Create(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.DistinctUntilChanged(observer)));\n        }\n\n        public static IAsyncObservable<TSource> DistinctUntilChanged<TSource>(IAsyncObservable<TSource> source, IEqualityComparer<TSource> comparer)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return Create(\n                source,\n                comparer,\n                static (source, comparer, observer) => source.SubscribeSafeAsync(AsyncObserver.DistinctUntilChanged(observer, comparer)));\n        }\n\n        public static IAsyncObservable<TSource> DistinctUntilChanged<TSource, TKey>(IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n\n            return Create(\n                source,\n                keySelector,\n                static (source, keySelector, observer) => source.SubscribeSafeAsync(AsyncObserver.DistinctUntilChanged(observer, keySelector)));","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/DistinctUntilChanged.cs#L7-L43","documentation":"ArgumentNullException thrown synchronously by the DistinctUntilChanged(source, comparer) overload when the IEqualityComparer<TSource> argument is null. The comparer is required because the operator must compare consecutive elements; there is no default-fallback in this overload (use the single-argument overload for default comparison).","triggerScenarios":"Calling DistinctUntilChanged(source, null) explicitly, or passing a comparer variable/field that was never assigned, or a factory method that returned null for the comparer.","commonSituations":"Conditional comparer selection where the else-branch leaves the variable null; DI-resolved comparers not registered; config-driven comparer lookup miss.","solutions":["Pass a real comparer, e.g. EqualityComparer<TSource>.Default","Use the comparer-less overload DistinctUntilChanged(source) when default equality is intended","Fix the comparer factory/lookup returning null"],"exampleFix":"// before\nvar result = source.DistinctUntilChanged(comparer); // comparer may be null\n// after\nvar result = source.DistinctUntilChanged(comparer ?? EqualityComparer<MyType>.Default);","handlingStrategy":"validation","validationCode":"if (comparer is null) comparer = EqualityComparer<TSource>.Default;","typeGuard":"static bool HasComparer<T>(IEqualityComparer<T>? c) => c is not null;","tryCatchPattern":"try { var r = source.DistinctUntilChanged(cmp); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"comparer\") { /* fall back to default comparer */ }","preventionTips":["Default comparer variables to EqualityComparer<T>.Default at declaration","Avoid conditional comparer assignment that can leave the variable null","Register comparers in DI before pipelines consume them"],"tags":["null-argument","icomparer","argument-validation"],"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"}