How to Resolve Error "CS0053: Inconsistent accessibility: property type 'type' is less accessible than property 'property'" in C#
The Compiler Error CS0053 is an Encapsulation error specifically related to Properties. For example, a message could be: "Inconsistent accessibility: property type 'MyType' is less accessible than property 'MyProperty'".
This error occurs when you declare a Property with a high visibility level (like public), but the data type that the property returns or sets has a lower visibility level (like internal or private). The compiler blocks this because you are creating a public gateway to a private or restricted data type, which external code would not know how to handle.
This guide explains the rules of visibility mismatch and how to align your properties with their types.
Understanding the Accessibility Gap
In C#, members (like properties) and types (like classes) have access modifiers:
public: Visible to the entire world.internal: Visible only within the current project (DLL).private: Visible only within the defining class.
The Rule: A property cannot be more visible than the type it exposes.
If you define public MyClass Data { get; set; }, you are promising that anyone can read or write Data. However, if MyClass is internal, external callers cannot see MyClass, making the property unusable to them. The compiler prevents this logical impossibility.
Scenario 1: Public Property with Internal Class
This is the most common cause. Classes in C# are internal by default if no modifier is specified. If you create a data model and forget to mark it public, but then try to return it from a public property, this error triggers.
Example of Mistake:
// No modifier = 'internal' (visible only inside this project)
class UserSettings
{
public bool IsDarkMode;
}
public class Application
{
// ⛔️ Error CS0053: Inconsistent accessibility
// The property 'Settings' is PUBLIC.
// But the return type 'UserSettings' is INTERNAL.
// Code in another DLL could call this property but wouldn't be able
// to see the 'UserSettings' class to hold the result.
public UserSettings Settings { get; set; }
}
Scenario 2: Exposing Private Nested Types
This occurs when you use a private class (usually for internal implementation details) but accidentally try to expose it via a public property.
Example of Mistake:
public class Car
{
// A private inner class (Implementation detail)
private class EngineSpec
{
public int Horsepower;
}
// ⛔️ Error CS0053: Inconsistent accessibility
// 'EngineSpec' is private to 'Car'.
// You cannot return it via a public property.
public EngineSpec Specs { get; set; }
}
Solution 1: Make the Type Public
If the property represents data that the outside world is supposed to see, use, and manipulate, you must ensure the Class definition is also public.
Fixing Scenario 1:
Add the public keyword to the class.
// ✅ Correct: Explicitly mark the class as public
public class UserSettings
{
public bool IsDarkMode;
}
public class Application
{
// Now valid because both the property and the type are public
public UserSettings Settings { get; set; }
}
Solution 2: Restrict the Property
If the type is meant to be internal (an implementation detail), then the property exposing it should not be public. Lower the property's visibility to match the type.
Fixing Scenario 1:
Change the property to internal.
internal class UserSettings
{
public bool IsDarkMode;
}
public class Application
{
// ✅ Correct: The property is now 'internal', matching the class.
// Only code inside this project can access this property.
internal UserSettings Settings { get; set; }
}
Solution 3: Use Interfaces (Best Practice)
Sometimes you want to keep the concrete class internal (to hide logic) but still allow public access to the data via a Property. You can do this by making the property return a Public Interface.
// 1. Define a PUBLIC interface
public interface ISettings
{
bool IsDarkMode { get; set; }
}
// 2. The concrete class is INTERNAL (Hidden implementation)
internal class UserSettings : ISettings
{
public bool IsDarkMode { get; set; }
}
public class Application
{
// 3. The property is PUBLIC, but returns the Interface
// ✅ Correct: The outside world sees 'ISettings' (public),
// even though the underlying object is 'UserSettings' (internal).
public ISettings Settings { get; set; } = new UserSettings();
}
Conclusion
CS0053 ensures that your API contract is valid.
- Check the Property: Is it
public? - Check the Return Type: Is the class definition
internalorprivate? - Align Them:
- Make the Class Public: If it is shared data.
- Make the Property Internal/Private: If it is internal logic.
- Use an Interface: If you want to expose functionality while hiding the implementation class.