{"record":{"id":"8f1db81df1bf0864","repo":"dotnet/reactive","slug":"conversion-fromeventpattern","errorCode":null,"errorMessage":"conversion","messagePattern":"conversion","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/FromEventPattern.cs","lineNumber":53,"sourceCode":"\n        public static IAsyncObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IAsyncScheduler scheduler)\n        {\n            if (addHandler == null)\n                throw new ArgumentNullException(nameof(addHandler));\n            if (removeHandler == null)\n                throw new ArgumentNullException(nameof(removeHandler));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return FromEvent<TDelegate, object, TEventArgs>(action => ConvertDelegate<Action<object, TEventArgs>, TDelegate>(action), addHandler, removeHandler, scheduler).Select(t => new EventPattern<TEventArgs>(t.arg1, t.arg2));\n        }\n\n        public static IAsyncObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler) => FromEventPattern<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, GetSchedulerForCurrentContext());\n\n        public static IAsyncObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IAsyncScheduler scheduler)\n        {\n            if (conversion == null)\n                throw new ArgumentNullException(nameof(conversion));\n            if (addHandler == null)\n                throw new ArgumentNullException(nameof(addHandler));\n            if (removeHandler == null)\n                throw new ArgumentNullException(nameof(removeHandler));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return FromEvent<TDelegate, object, TEventArgs>(action => conversion(new EventHandler<TEventArgs>((o, e) => action(o, e))), addHandler, removeHandler, scheduler).Select(t => new EventPattern<TEventArgs>(t.arg1, t.arg2));\n        }\n\n        public static IAsyncObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler) => FromEventPattern<TDelegate, TSender, TEventArgs>(addHandler, removeHandler, GetSchedulerForCurrentContext());\n\n        public static IAsyncObservable<EventPattern<TSender, TEventArgs>> FromEventPattern<TDelegate, TSender, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IAsyncScheduler scheduler)\n        {\n            if (addHandler == null)\n                throw new ArgumentNullException(nameof(addHandler));\n            if (removeHandler == null)\n                throw new ArgumentNullException(nameof(removeHandler));","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/FromEventPattern.cs#L35-L71","documentation":"System.ArgumentNullException with param name 'conversion'. The conversion-based overload FromEventPattern<TDelegate, TEventArgs>(conversion, addHandler, removeHandler, scheduler) expects a Func<EventHandler<TEventArgs>, TDelegate> that adapts the library's handler to your event's delegate type; a null conversion throws immediately because FromEvent cannot build handlers without it.","triggerScenarios":"Calling FromEventPattern(null, addHandler, removeHandler[, scheduler]) with any of the conversion-based overloads, e.g. FromEventPattern<SomeDelegate, EventArgs>(null, h => e.AddHandler(h), h => e.RemoveHandler(h)).","commonSituations":"A converter factory method returns null (unsupported delegate type), or the developer intended the non-conversion overload but called the conversion one and left the first argument null.","solutions":["Provide a real conversion, e.g. h => (SomeDelegate)((o, ev) => h(o, ev)) or a custom cast for non-standard delegates.","If standard EventHandler<TEventArgs> compatibility suffices, drop the conversion argument and use the non-conversion overload.","Fix the factory producing the conversion so it never returns null (throw with a clear message instead).","Check argument order — conversion is the FIRST parameter of this overload."],"exampleFix":"// before\nvar obs = AsyncObservable.FromEventPattern<MyDelegate, MyArgs>(\n    null,\n    h => target.E += h,\n    h => target.E -= h);\n// after\nvar obs = AsyncObservable.FromEventPattern<MyDelegate, MyArgs>(\n    h => new MyDelegate((o, a) => h(o, a)),\n    x => target.E += x,\n    x => target.E -= x);","handlingStrategy":"validation","validationCode":"if (conversion == null) throw new ArgumentNullException(nameof(conversion));\n// ensure your converter never returns null for supported delegate types","typeGuard":"static bool ValidConversion<TDelegate>(Func<EventHandler<TEventArgs>, TDelegate> conv) => conv != null;","tryCatchPattern":"try\n{\n    var obs = AsyncObservable.FromEventPattern<MyDelegate, MyArgs>(conversion, add, remove);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"conversion\")\n{\n    // conversion was null; supply a handler adapter\n}","preventionTips":["Remember conversion is the FIRST parameter of this overload.","Use the non-conversion overload for EventHandler<TEventArgs>-compatible delegates.","Make converter factories throw with a clear message instead of returning null.","Cover each custom delegate conversion in unit tests."],"tags":["argument-null","delegate-conversion","reactive-extensions","dotnet"],"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"}