Question Details

No question body available.

Tags

c# code-analysis roslyn-code-analysis

Answers (1)

May 16, 2026 Score: 8 Rep: 295,168 Quality: High Completeness: 60%

it is unpredictable whether a subscriber to the derived event will actually be subscribing to the base class event.

"Unpredictable" is in the sense that you don't know what the overridden implementation would be doing. This is similar to the bad practice of calling virtual methods in a constructor. It is "unpredictable" whether the overridden implementation of those methods will be accessing state that you haven't initialised yet.

Suppose the base class is

public class Base {
    public virtual event EventHandler? E;

public void RaiseE() => E?.Invoke(this, EventArgs.Empty); }

And someone else could write derived classes like this:

public class DerivedA: Base {
    public override event EventHandler? E;
}

public class DerivedB: Base { public override event EventHandler? E { add => Console.WriteLine("add is called!"); remove => Console.WriteLine("remove is called!"); } }

public class DerivedC: Base { public override event EventHandler? E { add => base.E += value; remove => base.E -= value; } }

Of these, only DerivedC's implementation is "subscribing to the base class event".

Focus on DerivedA. By overriding this way, DerivedA now has its own backing delegate field for the event (a different one from the one in Base), and += and -= will now always operate on the delegate field in DerivedA. However, RaiseA will still be invoking the delegate field in Base, which can no one can subscribe to, now that the event accessors have been overridden.

To put this in code,

Base b = new DerivedA();
b.E += (, ) => Console.WriteLine("Hi!");
b.RaiseE(); // doesn't print anything!

We end up in a situation where the event in the base class is effectively useless - the derived class can't raise it, and no one can subscribe to it, so the base class raising it will do nothing either. A very peculiar situation indeed.


This is similar to the situation where you override a property with an auto-property.

public class Base {
    public virtual int X { get; set; }
}
public class Derived {
    public override int X { get; set; }
}

Similar to events, Derived declares its own backing field for X, and the backing field in Base becomes useless. But at least the base class can still get and set the backing field in the derived class through the property, and wouldn't notice anything wrong. With events, the base class cannot raise the event in the derived class. All it can do is raise its own event, which will never have any subscribers.