How to Resolve Error "CS0069: An event in an interface cannot have add or remove accessors" in C#
The Compiler Error CS0069 is an interface declaration error. The message reads: "An event in an interface cannot have add or remove accessors".
In C#, an Interface is a contract that describes the public members a class must have. It defines the signature of an event, but it does not define the mechanism for how subscribers are added or removed. Writing add { } and remove { } blocks is considered an implementation detail, which (traditionally) belongs in the class, not the interface.
This guide explains the correct syntax for declaring events in interfaces.
Understanding Event Signatures
When you declare a property in an interface, you indicate whether it has a getter or setter:
string Name { get; set; } // Valid Interface Property
However, events work differently. An event in an interface is purely a declaration that "this type allows subscription." The internal logic of managing that subscription (the add and remove accessors) is left entirely to the implementing class.
The compiler expects an interface event to look like a simple field declaration, ending with a semicolon.
Scenario: The Invalid Declaration
This error usually happens when a developer tries to define an empty implementation or custom logic directly inside the interface file.
Example of error:
using System;
public interface IButton
{
// ⛔️ Error CS0069: An event in an interface cannot have add or remove accessors
// The interface cannot contain the implementation logic '{}'.
event EventHandler Clicked
{
add { }
remove { }
}
}
Solution: Remove the Accessors
To fix the error, strip away the curly braces and the accessors. End the declaration with a semicolon.
using System;
public interface IButton
{
// ✅ Correct: Just declare the event type and name.
event EventHandler Clicked;
}
This syntax tells the compiler: "Any class implementing IButton MUST provide a public event named Clicked of type EventHandler."
Implementing Custom Accessors in the Class
If your specific goal was to write custom logic (e.g., to forward the event to another object, or to filter subscribers), you must place that code in the Class that implements the interface, not in the interface itself.
using System;
public interface IButton
{
event EventHandler Clicked;
}
public class WindowsButton : IButton
{
// A private field to store the delegate manually (if needed)
private EventHandler _clickHandlers;
// ✅ Correct: The Class implements the Interface and provides the accessors here
public event EventHandler Clicked
{
add
{
Console.WriteLine("Subscriber added!");
_clickHandlers += value;
}
remove
{
Console.WriteLine("Subscriber removed!");
_clickHandlers -= value;
}
}
}
Alternatively, for standard behavior, the class implementation is just:
public class SimpleButton : IButton
{
// The compiler automatically generates default add/remove accessors for this
public event EventHandler Clicked;
}
Conclusion
CS0069 enforces the rule that interfaces are definitions, not implementations.
- Check Interface Files: Ensure your interface events end with a semicolon
;. - Remove Braces: Do not include
add { }orremove { }blocks inside theinterfacedefinition. - Move Logic: If you need custom subscription logic, move it to the concrete class implementing that interface.