{"record":{"id":"207cc0d4cc84da13","repo":"dotnet/reactive","slug":"comparer-parameter-comparer","errorCode":null,"errorMessage":"comparer (Parameter 'comparer')","messagePattern":"comparer \\(Parameter 'comparer'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Concurrency/ScheduledItem.cs","lineNumber":30,"sourceCode":"    /// </summary>\n    /// <typeparam name=\"TAbsolute\">Absolute time representation type.</typeparam>\n#pragma warning disable CA1033, CA1063, CA1816 // (Overridable IDisposable.) This is a specialized base type, and it would be inappropriate to encourage anyone to build derived types that do more in Dispose.\n    public abstract class ScheduledItem<TAbsolute> : IScheduledItem<TAbsolute>, IComparable<ScheduledItem<TAbsolute>>, IDisposable\n        where TAbsolute : IComparable<TAbsolute>\n    {\n        private SingleAssignmentDisposableValue _disposable;\n        private readonly IComparer<TAbsolute> _comparer;\n\n        /// <summary>\n        /// Creates a new scheduled work item to run at the specified time.\n        /// </summary>\n        /// <param name=\"dueTime\">Absolute time at which the work item has to be executed.</param>\n        /// <param name=\"comparer\">Comparer used to compare work items based on their scheduled time.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"comparer\"/> is <c>null</c>.</exception>\n        protected ScheduledItem(TAbsolute dueTime, IComparer<TAbsolute> comparer)\n        {\n            DueTime = dueTime;\n            _comparer = comparer ?? throw new ArgumentNullException(nameof(comparer));\n        }\n\n        /// <summary>\n        /// Gets the absolute time at which the item is due for invocation.\n        /// </summary>\n        public TAbsolute DueTime { get; }\n\n        /// <summary>\n        /// Invokes the work item.\n        /// </summary>\n        public void Invoke()\n        {\n            if (!_disposable.IsDisposed)\n            {\n                _disposable.Disposable = InvokeCore();\n            }\n        }\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Concurrency/ScheduledItem.cs#L12-L48","documentation":"The protected ScheduledItem<TAbsolute>.ctor(dueTime, comparer) throws ArgumentNullException when comparer is null. The comparer orders work items inside priority-queue-based schedulers (e.g. VirtualTimeScheduler, PriorityQueue) and is required for every enqueue, so the base constructor validates it immediately.","triggerScenarios":"Writing a custom ScheduledItem subclass that calls base(dueTime, null), or constructing built-in ScheduledItem variants through helper code that resolves an IComparer<TAbsolute> dynamically and gets null.","commonSituations":"Custom virtual-time schedulers for unit tests where a Comparer was forgotten; generics with default-comparer helpers returning null instead of Comparer<T>.Default; DI-injected comparer services not registered.","solutions":["Pass Comparer<TAbsolute>.Default when no custom ordering is needed.","Implement or register an IComparer<TAbsolute> and ensure it is non-null before constructing.","In subclass constructors, guard: 'base(dueTime, comparer ?? Comparer<TAbsolute>.Default)'.","Check DI registration for the comparer service."],"exampleFix":"// before\nprotected MyItem(DateTimeOffset dueTime, IComparer<DateTimeOffset> comparer) : base(dueTime, comparer) { }\n// after\nprotected MyItem(DateTimeOffset dueTime, IComparer<DateTimeOffset> comparer)\n    : base(dueTime, comparer ?? Comparer<DateTimeOffset>.Default) { }","handlingStrategy":"validation","validationCode":"if (comparer == null)\n    comparer = Comparer<TAbsolute>.Default;","typeGuard":"bool HasComparer<TAbsolute>(IComparer<TAbsolute> c) => c is not null;","tryCatchPattern":"try\n{\n    var item = new MyScheduledItem(dueTime, comparer);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"comparer\")\n{\n    var item = new MyScheduledItem(dueTime, Comparer<TAbsolute>.Default);\n}","preventionTips":["Default to Comparer<T>.Default in subclass constructors.","Never resolve comparers to null; provide a registered default implementation.","Unit-test custom ScheduledItem subclasses with an explicitly supplied comparer."],"tags":["rx","scheduler","argument-null","comparer","csharp"],"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"}