{"record":{"id":"a68a520975fb6aab","repo":"dotnet/reactive","slug":"strings-linq-event-sender-not-assignable","errorCode":null,"errorMessage":"Strings_Linq.EVENT_SENDER_NOT_ASSIGNABLE","messagePattern":"Strings_Linq\\.EVENT_SENDER_NOT_ASSIGNABLE","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs","lineNumber":82,"sourceCode":"                {\n                    throw new InvalidOperationException(Strings_Linq.EVENT_WINRT_REMOVE_METHOD_SHOULD_TAKE_ERT);\n                }\n            }\n\n            delegateType = psa[0].ParameterType;\n\n            var invokeMethod = delegateType.GetMethod(\"Invoke\")!; // NB: Delegates always have an Invoke method.\n\n            var parameters = invokeMethod.GetParameters();\n\n            if (parameters.Length != 2)\n            {\n                throw new InvalidOperationException(Strings_Linq.EVENT_PATTERN_REQUIRES_TWO_PARAMETERS);\n            }\n\n            if (!typeof(TSender).IsAssignableFrom(parameters[0].ParameterType))\n            {\n                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_SENDER_NOT_ASSIGNABLE, typeof(TSender).FullName));\n            }\n\n            if (!typeof(TEventArgs).IsAssignableFrom(parameters[1].ParameterType))\n            {\n                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_ARGS_NOT_ASSIGNABLE, typeof(TEventArgs).FullName));\n            }\n\n            if (invokeMethod.ReturnType != typeof(void))\n            {\n                throw new InvalidOperationException(Strings_Linq.EVENT_MUST_RETURN_VOID);\n            }\n        }\n\n        /// <summary>\n        /// Determine whether a type represents a WinRT event registration token\n        /// (https://learn.microsoft.com/en-us/uwp/api/windows.foundation.eventregistrationtoken).\n        /// </summary>\n        /// <param name=\"t\">The type to check.</param>","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs#L64-L100","documentation":"FromEventPattern<TSender, TEventArgs> requires that the event's delegate first parameter type is assignable from TSender. When the delegate's sender parameter is not compatible with the supplied TSender type argument, GetEventMethods throws InvalidOperationException naming the requested TSender full name.","triggerScenarios":"Calling FromEventPattern<Control, EventArgs>(...) for an event whose delegate's first parameter is object (or a type not related to Control), or any mismatched TSender such as using a derived/mostly-unrelated type.","commonSituations":"WinForms/WPF events whose sender is object but users specify a concrete control type; typos in generic arguments copied from other events; events using custom sender types while callers assume object.","solutions":["Set TSender to a type the delegate's first parameter is assignable from — for typical CLR events use FromEventPattern<object, TEventArgs>.","Match the delegate exactly: if the event uses EventHandler, TSender must be object.","Alternatively use the non-generic FromEventPattern(eventTarget, eventName) overload and let the library infer types."],"exampleFix":"// before\nObservable.FromEventPattern<Button, EventArgs>(b, nameof(b.Click));\n// after (Click is EventHandler, sender is object)\nObservable.FromEventPattern<object, EventArgs>(b, nameof(b.Click));","handlingStrategy":"validation","validationCode":"var invoke = typeof(EventHandler).GetMethod(\"Invoke\");\nvar senderType = invoke.GetParameters()[0].ParameterType;\nif (!senderType.IsAssignableFrom(typeof(TSender)))\n    throw new ArgumentException($\"TSender must be assignable from {senderType.Name}\");","typeGuard":null,"tryCatchPattern":"try\n{\n    var src = Observable.FromEventPattern<TSender, TEventArgs>(target, eventName);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"sender\"))\n{\n    var src2 = Observable.FromEventPattern<object, TEventArgs>(target, eventName);\n}","preventionTips":["Default to FromEventPattern<object, TEventArgs> for standard CLR events.","Read the delegate signature to pick TSender instead of copying generic arguments.","Prefer the overload inferring types from the event itself."],"tags":["generics","events","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}