Skip to main content

How to Resolve Error "CS0059: Inconsistent accessibility: parameter type 'type' is less accessible than delegate 'delegate'" in C#

The Compiler Error CS0059 is an Encapsulation error related to Delegates. For example, a message could be: "Inconsistent accessibility: parameter type 'MyType' is less accessible than delegate 'MyDelegate'".

In C#, a delegate defines a method signature. If you mark a delegate as public, you allow any code (internal or external) to invoke it or subscribe to it. However, if the delegate requires a parameter whose type is hidden (e.g., internal or private), external code would be unable to provide that argument. The compiler prevents this logical deadlock.

This guide explains the visibility rules for delegate parameters and how to resolve this error.

Understanding Delegate Parameter Accessibility

A delegate definition looks like this: public delegate void MyHandler(ParamType p);

  • public Delegate: Visible to the entire world.
  • internal ParamType: Visible only within the current project.

The Rule: A delegate cannot be more visible than its parameters. If MyHandler is public, an external caller is allowed to create a method that matches this signature. But to do so, they need to define a method that takes ParamType as an input. If they cannot see ParamType, they cannot write the method, rendering the delegate unusable.

Scenario 1: Public Delegate with Internal Parameter

This is a common oversight when defining Events. You create a custom event argument class but forget to make it public (classes are internal by default), and then try to use it in a public delegate or event.

Example of error:

// No modifier = 'internal' (visible only inside this project)
class LoginDetails
{
public string Username;
}

// ⛔️ Error CS0059: Inconsistent accessibility
// The delegate is PUBLIC.
// But the parameter 'LoginDetails' is INTERNAL.
// External code cannot subscribe to this delegate because
// they cannot accept 'LoginDetails' as an argument.
public delegate void LoginHandler(LoginDetails details);
note

This error also frequently occurs when using the generic EventHandler<T> with an internal class: public event EventHandler<LoginDetails> OnLogin;

Solution 1: Make the Parameter Type Public

If the data being passed (the parameter) is intended for public use, the class definition must be public.

Solution: add the public keyword to the parameter class.

// ✅ Correct: Explicitly mark the parameter type as public
public class LoginDetails
{
public string Username;
}

// Now valid because both the delegate and the parameter are public.
public delegate void LoginHandler(LoginDetails details);

Solution 2: Restrict the Delegate

If the parameter type is an internal implementation detail (e.g., a specific configuration object intended only for internal logic), then the delegate utilizing it should not be public. Restrict the delegate to internal.

Solution: change the delegate to internal.

internal class LoginDetails // Remains internal
{
public string Username;
}

// ✅ Correct: The delegate is now 'internal'.
// Only code inside this project (which can see 'LoginDetails') can use this delegate.
internal delegate void LoginHandler(LoginDetails details);

Conclusion

CS0059 ensures that the inputs required by your delegates are accessible to the people using them.

  1. Check the Delegate: Is it declared as public delegate ...?
  2. Check the Parameters: Look at the types inside the parentheses (TypeA a, TypeB b). Are they internal or private?
  3. Align Them:
    • Make the Parameter Class Public: If external users need to handle this data.
    • Make the Delegate Internal: If this is an internal event or callback mechanism.