How to Resolve Error "CS0060: Inconsistent accessibility: base class 'Class1' is less accessible than class 'Class2'" in C#
The Compiler Error CS0060 is an Inheritance visibility error. The message reads: "Inconsistent accessibility: base class 'Parent' is less accessible than class 'Child'".
This error enforces a fundamental rule of Object-Oriented Programming in C#: You cannot build a public house on a secret foundation. If you define a public class (visible to the world), it cannot inherit from an internal or private class (hidden types). Because the derived class is the base class (Inheritance), exposing the derived class implies exposing the base class. If the base is hidden, the contract is invalid.
This guide explains how to align the visibility of your class hierarchy to resolve this error.
Understanding the Inheritance Rule
In C#, a derived class inherits all members (methods, fields, properties) of the base class.
- If
Childis public, external code can create instances of it. - Since
Childinherits fromParent, external code could theoretically castChildtoParentor callParent's methods. - If
Parentis internal, external code doesn't knowParentexists.
This creates a paradox: The compiler cannot allow the outside world to use Child if it relies on a definition (Parent) that the outside world is forbidden to see.
The Rule: A base class must be at least as accessible as the class deriving from it.
Scenario 1: Public Child, Internal Base (The Default Trap)
This is the most frequent cause. In C#, if you declare a class without an access modifier (e.g., class MyBase), it defaults to internal. If you then create a derived class explicitly marked as public, you trigger CS0060.
Example of error:
// No modifier = 'internal' (visible only inside this project)
class BaseConfig
{
public string ConnectionString;
}
// ⛔️ Error CS0060: Inconsistent accessibility:
// base class 'BaseConfig' is less accessible than class 'DatabaseConnection'.
// 'DatabaseConnection' is PUBLIC (Open to the world).
// 'BaseConfig' is INTERNAL (Hidden).
public class DatabaseConnection : BaseConfig
{
public void Connect() { ... }
}
Solution 1: Make the Base Class Public
If the hierarchy is intended to be part of your public API (i.e., you want users to interact with both the Child and the logic inherited from the Parent), you must make the Base class public.
Solution: add the public keyword to the base class.
// ✅ Correct: Explicitly mark the base as public
public class BaseConfig
{
public string ConnectionString;
}
// Now valid because both classes are public.
public class DatabaseConnection : BaseConfig
{
public void Connect() { ... }
}
Solution 2: Restrict the Derived Class
If the Base class is an implementation detail that should remain hidden (internal), then the Child class typically shouldn't be public either. You should restrict the Child class to match the Base class's visibility.
Solution: change the derived class to internal.
internal class BaseConfig // Remains internal
{
public string ConnectionString;
}
// ✅ Correct: The derived class is now 'internal'.
// It is no longer more visible than its parent.
internal class DatabaseConnection : BaseConfig
{
public void Connect() { ... }
}
What if I need the Child to be Public but the Parent Internal?
You cannot use Inheritance for this. Instead, use Composition.
Make the BaseConfig a private or internal field inside the DatabaseConnection class, rather than inheriting from it.
internal class BaseConfig { ... }
public class DatabaseConnection
{
private BaseConfig _config = new BaseConfig(); // Composition
}
Conclusion
CS0060 ensures the integrity of your type hierarchy.
- Check the Child: Is the derived class
public? - Check the Parent: Is the base class
internal(default) orprivate? - Align Them:
- Make Base Public: If the entire hierarchy is for public consumption.
- Make Child Internal: If the hierarchy is for internal use only.
- Use Composition: If you want to hide the implementation details of the base logic while exposing the child.