Field-like events are events that do
not have explicit add and remove accessors.
public event EventHandler MyEvent; // No add and remove accessors
The compiler generates a private delegate field to back the event, as well as generating the implicit add
and remove accessors.
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.
Noncompliant code example
abstract class Car
{
public virtual event EventHandler OnRefuel; // Noncompliant
public void Refuel()
{
// This OnRefuel will always be null
if (OnRefuel != null)
{
OnRefuel(this, EventArgs.Empty);
}
}
}
class R2 : Car
{
public override event EventHandler OnRefuel;
}
class Program
{
static void Main(string[] args)
{
var r2 = new R2();
r2.OnRefuel += (o, a) =>
{
Console.WriteLine("This event will be called");
};
r2.Refuel();
}
}
Compliant solution
To prevent this, remove the virtual designation from the parent class event.
abstract class Car
{
public event EventHandler OnRefuel; // Compliant
public void Refuel()
{
if (OnRefuel != null)
{
OnRefuel(this, EventArgs.Empty);
}
}
}
class R2 : Car
{
}
class Program
{
static void Main(string[] args)
{
var r2 = new R2();
r2.OnRefuel += (o, a) =>
{
Console.WriteLine("This event will be called");
};
r2.Refuel();
}
}