Event handler signature does not follow the (sender, e) convention
ID |
vbnet.maintainability.declare_event_handlers_correctly |
Severity |
high |
Remediation Complexity |
medium |
Remediation Risk |
medium |
Remediation Effort |
low |
Resource |
Api Design |
Language |
VB.NET |
Description
Reports a Sub attached to an event with a Handles clause whose parameter list is not the
conventional (sender As Object, e As EventArgs) - a sender typed as something more specific
than Object, the two parameters in the wrong order, a single parameter, or extra parameters
after the event arguments. The event-arguments parameter may be any type whose name ends in
EventArgs, and ByVal and a System. prefix are accepted. Handlers that declare no
parameters at all are not reported.
Rationale
The Handles clause accepts a signature narrower than the event it subscribes to, so the
compiler does not object; the failure arrives at run time, on the path that raises the event.
A handler that declares sender As Button is bound to an event that passes Object, and the
moment the same handler is reused for a control of another type - a LinkLabel, a menu item,
or the form itself raising the event on behalf of a child - the cast fails and the exception
surfaces inside the event source, far from the handler that caused it. A single-parameter or
reordered signature has the same character: it compiles, it works for the one wiring it was
written against, and it silently rules out every other producer of that event. The convention
also carries information the handler needs. sender is what lets one handler serve several
controls and still know which one was clicked, and the e argument is where a Cancel flag,
a key code or a mouse position lives - a handler that omits it cannot participate in those
protocols, and a handler that adds parameters beyond it cannot be reached through the delegate
at all except by VB’s relaxed conversion, quietly discarding what the extra parameter was for.
The following code illustrates the pattern detected by this rule:
Public Class OrderForm
Inherits Form
' FLAGGED: Event handler signature does not follow the (sender, e) convention
Private Sub OnSaveClick(sender As Button, e As EventArgs) Handles btnSave.Click
Save()
End Sub
Remediation
Declare the handler as (sender As Object, e As TEventArgs), matching the event’s argument type,
and cast or use TryCast on sender inside the body when the specific control is needed. Where
a handler needs additional context, capture it from the form’s state or from sender rather than
adding parameters, and where the same logic is wanted from non-event code, put it in a separate
method the handler calls.
' Before: fails at run time as soon as another control raises the event
Private Sub OnSaveClick(sender As Button, e As EventArgs) Handles btnSave.Click
Save()
End Sub
' After
Private Sub OnSaveClick(sender As Object, e As EventArgs) Handles btnSave.Click
Dim clicked = TryCast(sender, Button)
Save()
End Sub