tags:

views:

353

answers:

4
class MyBase
{
    protected object PropertyOfBase { get; set; }
}

class MyType : MyBase
{
    void MyMethod(MyBase parameter)
    {
        // I am looking for:
        object p = parameter.PropertyOfBase;  // error CS1540: Cannot access protected member 'MyBase.PropertyOfBase' via a qualifier of type 'MyBase'; the qualifier must be of type 'MyType' (or derived from it)
    }
}

Is there a way to get a protected property of a parameter of a type from an extending type without reflection? Since the extending class knows of the property through its base type, it would make sense if possible.

+6  A: 

No, you can't do this.

You're only allowed to access protected members of objects of the accessing type (or derived from it). Here, we don't know whether the parameter is of type MyType or SomeOtherCompletelyDifferentType.

EDIT: The relevant bit of the C# 3.0 spec is section 3.5.3:

When a protected instance member is accessed outside the program text of the class in which it is declared, and when a protected internal instance member is accessed outside the program text of the program in which it is declared, the access must take place within a class declaration that derives from the class in which it is declared. Furthermore, the access is required to take place through an instance of that derived class type or a class type constructed from it. This restriction prevents one derived class from accessing protected members of other derived classes, even when the members are inherited from the same base class.

Jon Skeet
We do not know if it is MyType or SomeOtherCompletelyDifferentType but we know it is MyBase and we know MyBase has a property named PropertyOfBase so it still makes sense to me.
Serhat Özgel
The spec disagrees :) This is the defined meaning of protected access.
Jon Skeet
Wow, it is impossible by design. Thank you.
Serhat Özgel
Hmm, but it says "when the members are inherited from the same base class", not "when the members are same". I am still not totally satisfied :)
Serhat Özgel
There's no concept of "the members are the same". It means "even when you're trying to get at member Base.X in an instance of Derived2 from an instance of Derived1, where Derived1 and Derived2 both derive from Base."
Jon Skeet
I already understood that but my previous statement has a mistake: for a moment I assumed parameter is MyType which clearly is not case. Now it is clear. Thanks.
Serhat Özgel
+2  A: 

A protected property is only accessible to an instance of a derived class, not to instances of derived classes.

There is a difference and it does make sense, protected members should not give up their value to any other instance, even an instance derived from the same type.

(Edited, got myself a bit tongue tied!)

But if the parameter was of MyType, it would be accessible to this instance and this is clearly an "other" instance.
Serhat Özgel
Well said, I didnt know that would work!
+4  A: 

There's a good reason you can't do this. Suppose someone writes:

class Other : MyBase { }

new MyType().MyMethod(new Other());

If the language allowed what you're asking for, you could violate the assumed invariants of Other by modifying the value of PropertyOfBase.

Jay Bazuzi
A: 

I think you should ask yourself if there is a better way of doing what you want to do. You want PropertyOfBase to act as public in the context of MyType.MyMethod(), but to be protected in all other situations. Why?

unforgiven3