How to Resolve Error "CS0666: 'member' : new protected member declared in struct" in C#
The Compiler Error CS0666 is an access modifier restriction error. The message reads: "'MemberName' : new protected member declared in struct".
In C#, the protected access modifier means "accessible within this class and by derived class instances." However, structs in C# are implicitly sealed. This means you cannot inherit from a struct. Since it is impossible for a struct to have a derived child ("sub-struct"), the concept of protected access is logically impossible and therefore forbidden.
This guide explains the inheritance limitations of structs and how to choose the correct access modifier.
Understanding Structs and Inheritance
To understand CS0666, you must compare Classes and Structs:
- Classes: Support inheritance. You can have
class Child : Parent. Therefore,protectedmembers inParentmake sense becauseChildcan see them. - Structs: Do not support inheritance. A struct cannot inherit from another struct or class, and nothing can inherit from a struct.
Because a struct can never have children, declaring a member as protected (visible to children) is a contradiction.
Scenario: The Invalid Modifier
This error typically happens when a developer copies code from a class and pastes it into a struct, or when they attempt to implement an object-oriented hierarchy using value types.
Example of error:
public struct Coordinate
{
public int X;
public int Y;
// ⛔️ Error CS0666: 'Coordinate.Validate()': new protected member declared in struct
// Since nothing can inherit from 'Coordinate', nothing could ever use this method.
protected void Validate()
{
if (X < 0) X = 0;
}
}
This restriction also applies to compound modifiers involving protected, such as protected internal and private protected.
Solution 1: Use Private (Encapsulation)
If your intention was to hide the member from the outside world and keep it for internal use only, change the modifier to private.
Solution;
public struct Coordinate
{
public int X;
public int Y;
// ✅ Correct: 'private' restricts access to this struct only.
private void Validate()
{
if (X < 0) X = 0;
}
public void Update(int x)
{
X = x;
Validate(); // Internal call is valid
}
}
Solution 2: Use Public or Internal (Visibility)
If your intention was to expose the member to other parts of your code, you must choose a modifier that is valid for structs.
public: Visible to everyone.internal: Visible to everyone in the same project/assembly.
Solution:
public struct Coordinate
{
// ✅ Correct: 'internal' allows other classes in the same project to use this,
// which is often what developers mistakenly want when they type 'protected'.
internal void Reset()
{
X = 0;
Y = 0;
}
}
Conclusion
CS0666 is the compiler enforcing the definition of a Value Type.
- Remember: Structs are Sealed. They cannot have derived types.
- The Logic:
protectedmeans "Visible to Derived Types." Since there are no derived types,protectedis invalid. - The Fix:
- Use
privatefor internal logic. - Use
publicorinternalfor external access.
- Use