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

Configuration

This detector does not need any configuration.