Skip to main content

How to Resolve Error "CS0066: 'event': event must be of a delegate type" in C#

The Compiler Error CS0066 is a declaration error. The message reads: " 'MyEvent': event must be of a delegate type".

In C#, an Event is a mechanism that allows a class to notify other classes when something happens. Under the hood, an event is a wrapper around a Delegate. A delegate defines the "signature" (return type and parameters) of the methods that can subscribe to the event.

This error occurs when you attempt to declare an event using a type that is not a delegate—such as int, string, void, or a standard class.

Understanding Events and Delegates

An event declaration follows this syntax: access_modifier event DelegateType EventName;

The compiler needs the DelegateType to know:

  1. What kind of functions can subscribe to this event?
  2. What parameters should be passed when the event is raised?

If you declare public event int ScoreChanged, the compiler asks: "If ScoreChanged happens, how do I 'call' an integer?" Since an integer is data, not a function pointer, the declaration is invalid.

Scenario 1: Using Primitives (int, string, bool)

A common mistake is confusing the data associated with the event with the event type itself. You might want to pass an int when the event fires, so you try to declare the event as an int.

Example of Error

public class ScoreBoard
{
// ⛔️ Error CS0066: 'ScoreBoard.Score' : event must be of a delegate type
// 'int' is a value type, not a delegate.
public event int Score;
}

Solution: Use Action<T> or EventHandler<T>

If you want to transmit an integer, use a generic delegate that takes an integer as a parameter.

using System;

public class ScoreBoard
{
// ✅ Correct: Action<int> is a delegate representing a void method taking an int.
public event Action<int> ScoreChanged;

public void UpdateScore(int newScore)
{
// Raising the event
ScoreChanged?.Invoke(newScore);
}
}

Scenario 2: Confusing Method Syntax (void)

Beginners often confuse defining a method with defining an event. Since many methods return void, one might try to define an event as void.

Example of Error

public class Button
{
// ⛔️ Error CS0066: 'Button.Click': event must be of a delegate type
// 'void' is a return type keyword, not a type or delegate.
public event void Click;
}

Solution: Use Action or EventHandler

For an event with no data (void return, no parameters), use Action or the standard EventHandler.

using System;

public class Button
{
// ✅ Correct: 'Action' is a delegate for 'void Method()'
public event Action Click;

// ✅ Correct: 'EventHandler' is the .NET standard for events
public event EventHandler StandardClick;
}

Solution: Using Standard or Custom Delegates

To fix CS0066, ensure the type after the event keyword is a valid delegate. You have three main options.

This follows the standard pattern (object sender, EventArgs e).

using System;

public class Process
{
// Best practice for libraries and interoperability
public event EventHandler Completed;
}

Option B: Generic Action or Func

Useful for internal logic or lightweight callbacks where the "Sender/Args" pattern is too verbose.

using System;

public class Process
{
// Simple and direct
public event Action<string> LogMessage;
}

Option C: Custom Delegate

Useful if you need specific parameter names for clarity.

// 1. Define the delegate
public delegate void StatusUpdateHandler(int percent, string status);

public class Process
{
// 2. Use the delegate type in the event
public event StatusUpdateHandler Progress;
}
tip

In modern C#, Option A (EventHandler) or Option B (Action) covers 99% of use cases. You rarely need to define custom delegates (Option C) anymore.

Conclusion

CS0066 tells you that your event definition is structurally wrong.

  1. Identify the Event: Look for the event keyword.
  2. Check the Type: Look at the word immediately following event.
  3. Verify: Is it int, void, or string? These are invalid.
  4. Fix: Replace it with EventHandler, Action, or a custom delegate type.