How to Resolve Error "CS0055: Inconsistent accessibility: parameter type 'type' is less accessible than indexer 'indexer'" in C#
The Compiler Error CS0055 is an Encapsulation error specifically related to the arguments (parameters) of Indexers. For example, a message could be: "Inconsistent accessibility: parameter type 'MyKey' is less accessible than indexer 'this[MyKey]'".
This error occurs when you define a Public Indexer (allowing users to look up items like myObject[key]), but the type of the key you require is hidden (e.g., internal or private). The compiler prevents this because it creates a usability paradox: you are offering a public way to look up data, but you are requiring a "key" that the outside world is not allowed to see or create.
This guide explains how to ensure the accessibility of your indexer parameters matches the indexer itself.
Understanding Indexer Parameters
An indexer is defined with the signature: public ReturnType this[ParameterType key].
publicIndexer: Promises that any external code can use square brackets[]to access data.internalParameterType: The definition of the "key" is hidden from external code.
The Rule: If an indexer is public, the type of every parameter inside the brackets [...] must also be public.
If you have public string this[SecretKey k], but SecretKey is private, an external caller cannot construct a SecretKey to pass into the brackets.
Scenario 1: Public Indexer with Internal Key
This is a common mistake when building custom dictionaries or caches. You define a custom key class but forget to mark it public (defaulting to internal), then try to use it in a public indexer.
Example of Error:
// No modifier = 'internal' (visible only inside this project)
class UserKey
{
public int Id;
}
public class UserCache
{
// ⛔️ Error CS0055: Inconsistent accessibility
// The indexer is PUBLIC. It invites the world to call 'cache[key]'.
// But the parameter 'UserKey' is INTERNAL.
// External code cannot create or see 'UserKey', so they can't call this indexer.
public string this[UserKey key]
{
get { return "User Data"; }
set { }
}
}
Scenario 2: Private Nested Types as Keys
This happens when you use a private nested struct or class as a lookup handle, but accidentally expose the lookup mechanism publicly.
Example of Error:
public class TokenSystem
{
// A private implementation detail
private struct InternalToken
{
public string Hash;
}
// ⛔️ Error CS0055: Inconsistent accessibility
// You cannot require the caller to pass an 'InternalToken'
// because the caller is not allowed to know what 'InternalToken' is.
public bool this[InternalToken token]
{
get { return true; }
}
}
Solution 1: Make the Parameter Type Public
If the parameter (the key) is the intended way for users to look up data, the class definition for that key must be public.
Fixing Scenario 1:
Mark the UserKey class as public.
// ✅ Correct: The Key class is now visible to the world
public class UserKey
{
public int Id;
}
public class UserCache
{
// Now valid because both the indexer and the parameter are public
public string this[UserKey key]
{
get { return "User Data"; }
set { }
}
}
Solution 2: Restrict the Indexer
If the key type is an internal implementation detail and shouldn't be exposed, then the indexer utilizing it shouldn't be public. Change the indexer's visibility to match the key.
internal class UserKey // Still internal
{
public int Id;
}
public class UserCache
{
// ✅ Correct: The indexer is now 'internal'.
// Only code inside this project (which can see 'UserKey') can use this indexer.
internal string this[UserKey key]
{
get { return "User Data"; }
set { }
}
}
Solution 3: Use Interfaces (Abstraction)
If you want to keep the concrete key class internal (to hide its logic or constructor) but still allow public lookup, use a Public Interface as the parameter type.
// 1. Define a PUBLIC interface for the key
public interface IKey
{
int Id { get; }
}
// 2. The concrete key is INTERNAL (Hidden implementation)
internal class UserKey : IKey
{
public int Id { get; set; }
}
public class UserCache
{
// 3. The indexer accepts the PUBLIC Interface
// ✅ Correct: The caller passes an object implementing 'IKey'.
// They don't need to see the internal 'UserKey' class definition.
public string this[IKey key]
{
get { return "User Data based on ID: " + key.Id; }
set { }
}
}
When using this approach, you usually need a public "Factory Method" (e.g., public IKey CreateKey(...)) elsewhere in your class to let users create these keys, since they can't instantiate UserKey directly.
Conclusion
CS0055 ensures that the "keys" required by your indexers are accessible to the people using them.
- Check the Indexer: Look for
public ReturnType this[ParamType p]. - Check the Parameter: Is
ParamTypemarked asinternalorprivate? - Align Them:
- Make the Key Public: If users are expected to create keys manually.
- Make the Indexer Internal: If the lookup is for internal use only.
- Use an Interface: If you want to allow lookup while hiding the key's implementation.