Why is this an issue?
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();
}
}