Cannot use protected setter from derived class??

I have an Entity class that stores a bunch of values about a player (e.g., character name, team, etc.)

To keep my code clean, I’m trying to separate the job of initialization into another class, Entity_Initializer

Entity_Initializer derives from Entity, so it should have access to its protected variables.

But when I try to use an instance of the Entity_Initializer class to set the properties, I get an error.

For example, I have:

public class Entity_Initialization : Entity {

    Entity _entity;

    void Awake(){
        _entity = GetComponent<Entity> ();
        _entity.team = transform.parent.GetComponent<Team> ();
    }

The team field of the Entity class has a protected setter:

public class Entity : MonoBehaviour {

    public Team team { get; protected set; } // Reference to actor's team

_entity is of Class Entity, and the _entity.team = transform.parent.GetComponent (); command is occurring within a derived class, which should be able to use protected setters.

But I get this error:

Cannot access protected member Entity.team' via a qualifier of type Entity’. The qualifier must be of type `Entity_Initialization’ or derived from it

This doesn’t make sense to me.

You are not accessing the team property of the implemented entity class, but of a reference to an Entity class, which is not the same.

You can do:

Entity_Initialization.Team = // Some team;

You can’t do:

_entity.Team = // Some team;

btw just as a note, properties should use PascalCasing and not camelCasing.

Its not allowed because it would enable you to make cross-hierarchy calls.

basically it would allow someone to make a new class that derives from Entity (and not Entity_Initialization), access an Entity_Initialization instance, and change their team. thus a class that is NOT an Entity_Initialization could set a protected variable in it.

that would completely break encapsulation and the intent of “protected”. You can set “your” team or the team of another “Entity_Initialization” but not the team of a generic “Entity”

1 Like

Eek, I completely misunderstood how inheritance works with respect to private and protected members. In my defense the descriptions given on MDSN seem misleading.

This page says protected means “Access is limited to the containing class or types derived from the containing class.” and
This page says “When you define a class to derive from another class, the derived class implicitly gains all the members of the base class, except for its constructors and destructors.”

If “private” means only accessible to code within the class and “public” means accessible to code anywhere… then reading “protected” to mean “accessible to code in the class or derived classes” seems like the natural meaning. That is to say a protected field F of an instance X of a class B can be altered by code in a derived class C. But that is not the case.

It would be much more clear if they explicitly stated that “protected” only has any relevance for fields OF the derived type. In particular, if X is a protected field of a specific object O of class B, then the specific field O.X is just as hard to access as it would be if X were private. So “protected” does not in any way broaden the access to fields of instances of the base class. The only reason why it has any relevance at all is for fields of instances of derived classes in that if X were a private field of class B and object P is of class C derived from B, then P could not even access its own X field… so private field are, for all practical value, not inherited by instances of the derived class.

I have been reading up on C#, and I think every one of my books glosses over this. MDSN does eventually get around to explaining it, but it isn’t evident from its slug line.

I think to accomplish what I want to do, I should use a nested class instead.

I think the wording given in this answer on SO would be much better:

The “and not to instances of derived-class” is the key part missing from the MSDN definition.

Anyways, thanks for helping me get set straight on this.

That seems like a weird setup anyway. Inheritance is supposed to represent an “is a” relationship, like if Poodle inherits from Dog, it means a Poodle “is a” Dog. In this case you have an Entity attached to an object and then also a second Entity_Initialization attached to an object; it doesn’t seem like Entity_Initialization “is” an Entity; it seems like it’s some other separate class that does something “to” an Entity. In that case it should not inherit from Entity; there doesn’t seem to be any reason for that inheritance.