(This question is a follow-up to C# accessing protected member in derived class)
I have the following code snippet:
public class Fox
{
protected string FurColor;
private string furType;
public void PaintFox(Fox anotherFox)
{
anotherFox.FurColor = "Hey!";
anotherFox.furType = "Hey!";
}
}
public class RedFox : Fox
{
public void IncorrectPaintFox(Fox anotherFox)
{
// This one is inaccessible here and results in a compilation error.
anotherFox.FurColor = "Hey!";
}
public void CorrectPaintFox(RedFox anotherFox)
{
// This is perfectly valid.
anotherFox.FurColor = "Hey!";
}
}
Now, we know that private and protected fields are private and protected for type, not instance.
We also know that access modifiers should work at compile time.
So, here is the question - why can't I access the FurColor
field of the Fox
class instance in RedFox
? RedFox
is derived from Fox
, so the compiler knows it has access to the corresponding protected fields.
Also, as you can see in CorrectPaintFox
, I can access the protected field of the RedFox
class instance. So, why can't I expect the same from the Fox
class instance?
Simple reason is:
public void IncorrectPaintFox(Fox anotherFox)
{
anotherFox = new BlueFox();
// This one is inaccessible here and results in a compilation error.
anotherFox.FurColor = "Hey!";
}
Now you're not accessing the protected field from within BlueFox
, therefore since the compiler doesn't know what the runtime type is, it has to always make this an error.
To expand slightly on the accepted answer, the reason the compiler enforces this rule, as opposed to the much more lax meaning of protected
that PHP has, is because allowing the access you want to allow would make it possible to break the invariants of a class, by bypassing its defined protection levels. (Of course, this is always possible e.g. via Reflection, but the compiler at least makes it hard to do by accident).
The problem is that just knowing that some object is a Fox
does not make it safe for you to interact with its internal workings, because it may not actually be a Fox
at
runtime. Consider these classes:
public class Fox
{
protected Color FurColor;
}
public class RedFox
{
public RedFox ()
{
this.FurColor = Color.Red;
}
}
public class ArcticFox
{
public ArcticFox ()
{
this.FurColor = Color.White;
}
}
What you are asking is for the compiler to permit the following method, assuming it was defined on the RedFox
class:
public void PaintFoxRed ( Fox fox )
{
fox.FurColor = Color.Red;
}
But if that were legal, I could do this:
RedFox a = new RedFox();
Fox b = new ArcticFox();
a.PaintFoxRed(b);
My ArcticFox
is now red despite the class itself only allowing itself to be white.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With