No Virtual Field Like Event

ID

csharp.no_virtual_field_like_event

Severity

high

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

CSharp

Tags

code_smell, events, inheritance

Description

Reports field-like events declared virtual. A field-like event is written without an add/remove accessor block, so the compiler generates the backing delegate field and the accessors for it. Events with explicit accessors are not reported, and neither are non-virtual or abstract events.

Rationale

The delegate field behind a field-like event is private to the class that declares it. When a derived class overrides the event, it gets a second backing field of its own, and the two fields are unrelated. Handlers added through a base-typed reference go on the base list; handlers added through a derived-typed reference go on the derived list. Raising the event from the base class walks only the base list, raising it from the derived class only the derived list — so some subscribers are silently never called, and which ones depends on the static type at each subscription site rather than on anything visible at the declaration.

using System;

public class Publisher
{
    public virtual event EventHandler Started;              // FLAW - overriding splits the handler list

    public virtual event EventHandler Guarded               // OK - explicit accessors, an override can cooperate
    {
        add { guarded += value; }
        remove { guarded -= value; }
    }

    public event EventHandler Plain;                        // OK - not virtual

    private EventHandler guarded;
}

Remediation

Drop the virtual modifier and give derived classes a protected virtual OnStarted(…​) method that raises the event; overriding that method is the standard extension point and leaves a single invocation list. If the event itself really has to be overridable, write explicit add/remove accessors so the storage is under the author’s control and an override can delegate to the base implementation.