Skip to main content

How to Resolve Error "CS0074: 'event': abstract event cannot have initializer" in C#

The Compiler Error CS0074 is an inheritance design error. The message reads: " 'MyEvent': abstract event cannot have initializer".

In C#, the abstract keyword indicates that a member is missing its implementation and must be implemented by a derived class. An initializer (assigning a value like = null or = delegate {}) is a form of implementation—it implies creating a backing field and assigning data to it.

Because an abstract member is purely a contract with no storage or logic in the base class, trying to initialize it creates a contradiction.

This guide explains how to correctly define abstract events or provide default implementations.

Understanding Abstract Members

When you mark an event as abstract, you are telling the compiler: "I am not providing any logic or storage for this event in this class. Any class that inherits from me MUST define this event."

When you add an initializer (e.g., = delegate { }), you are saying: "Create a private field for this event and set its initial value to an empty delegate."

You cannot have "no storage" and "initial value" at the same time.

Scenario: Trying to Initialize an Abstract Event

A common C# pattern is to initialize events to an empty delegate to avoid null checks. Developers often try to combine this pattern with abstract to force derived classes to have the event while trying to provide "safe" default behavior.

Example of error:

using System;

public abstract class Device
{
// ⛔️ Error CS0074: 'Device.StatusChanged': abstract event cannot have initializer
// You cannot assign a value to something that doesn't exist yet.
public abstract event EventHandler StatusChanged = delegate { };
}

Solution 1: Remove the Initializer (Enforce Contract)

If your goal is to ensure that all child classes implement the event, keep the abstract keyword but remove the assignment. The responsibility of initializing the event falls to the derived class.

Step 1: Clean the Base Class

public abstract class Device
{
// ✅ Correct: Defines the contract. No implementation.
public abstract event EventHandler StatusChanged;
}

Step 2: Implement in Derived Class

public class Printer : Device
{
// ✅ Correct: The concrete class implements the abstract event.
// It can now include the initializer logic.
public override event EventHandler StatusChanged = delegate { };

public void Print()
{
// Safe to invoke because of the initializer above
StatusChanged(this, EventArgs.Empty);
}
}

Solution 2: Use Virtual Instead (Provide Default)

If your goal is to provide a "safe" event that is pre-initialized so derived classes don't have to worry about it, do not use abstract. Use virtual instead. This allows the base class to hold the logic, while still allowing derived classes to override it if necessary.

using System;

public abstract class Device
{
// ✅ Correct: 'virtual' allows implementation details (like the initializer).
// Derived classes inherit this behavior automatically.
public virtual event EventHandler StatusChanged = delegate { };

protected void RaiseStatusChanged()
{
// This works in the base class now
StatusChanged(this, EventArgs.Empty);
}
}
note

When to use Abstract vs. Virtual:

  • Abstract: "I don't know how this event handles subscribers, the child class must decide."
  • Virtual: "Here is a standard event implementation, but the child class can change it if needed."

Conclusion

CS0074 enforces the definition of abstract.

  1. If you need abstract: Remove the = ... part. The base class defines what, the derived class defines how.
  2. If you need initialization: Change abstract to virtual (or remove the modifier entirely if the class isn't abstract). This allows the base class to store the state.