Field-like events are events that do not have explicit add and remove methods. The compiler generates a private delegate field to back the event, as well as generating the implicit add and remove methods.

When a virtual field-like event is overridden by another field-like event, the behavior of the C# compiler is to generate a new private delegate field in the derived class, separate from the parent’s field. This results in multiple and separate events being created, which is rarely what’s actually intended.

To prevent this, remove the virtual designation from the parent class event.

Noncompliant Code Example

abstract class Car
{
  public virtual event EventHandler OnRefueled; // Noncompliant

  public void Refuel()
  {
    // This OnRefueled will always be null
     if (OnRefueled != null)
     {
       OnRefueled(this, null);
     }
  }
}

class R2 : Car
{
  public override event EventHandler OnRefueled;
}

class Program
{
  static void Main(string[] args)
  {
    var r2 = new R2();
    r2.OnRefueled += new EventHandler((o, a) =>
    {
      Console.WriteLine("This event will never be called");
    });
    r2.Refuel();
  }
}

Compliant Solution

abstract class Car
{
  public event EventHandler OnRefueled; // Compliant

  public void Refuel()
  {
    if (OnRefueled != null)
    {
      OnRefueled(this, null);
    }
  }
}

class R2 : Car {}

class Program
{
  static void Main(string[] args)
  {
    var r2 = new R2();
    r2.OnRefueled += new EventHandler((o, a) =>
    {
      Console.WriteLine("This event will be called");
    });
    r2.Refuel();
  }
}