Is there a way to reach a `protected` member of another object from a derived type?

后端 未结 7 1064
轻奢々
轻奢々 2020-11-30 13:41
class MyBase
{
    protected object PropertyOfBase { get; set; }
}

class MyType : MyBase
{
    void MyMethod(MyBase parameter)
    {
        // I am looking for:
           


        
相关标签:
7条回答
  • 2020-11-30 14:09

    You can also declare MyType as a nested class of MyBase (instead of inheriting), this way you can access private/protected members when you send the class MyBase as a parameter

    public class MyBase
    {
        protected object PropertyOfBase { get; set; }
    
        public class MyType
        {
            public void MyMethod(MyBase parameter)
            {
                object p = parameter.PropertyOfBase;  
            }
        }
    }
    

    To create an instance of MyType just use

    var t = new MyBase.MyType();
    t.MyMethod(new MyBase());
    
    0 讨论(0)
  • 2020-11-30 14:16

    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.

    0 讨论(0)
  • 2020-11-30 14:17

    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?

    0 讨论(0)
  • 2020-11-30 14:26

    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.

    0 讨论(0)
  • 2020-11-30 14:29

    Last time I faced a similar problem, I used the solution of adding a protected static method to the base:

    class MyBase
    {
        protected object PropertyOfBase { get; set; }
    
        protected static object GetPropertyOfBaseOf(MyBase obj) 
        {
            return obj.PropertyOfBase;
        }
    }
    
    class MyType : MyBase
    {
        void MyMethod(MyBase parameter)
        {
            object p = GetPropertyOfBaseOf(parameter);
        }
    }
    
    0 讨论(0)
  • 2020-11-30 14:32

    As you are inheriting from MyBase, you can access all fields/properties/methods from it marked as "protected" using the "base" keyword.

    public class MyBase
    {
        protected object PropertyOfBase { get; set; }
    }
    
    public class MyType : MyBase
    {
        void MyMethod()
        {
            object p =  base.PropertyOfBase;
        }
    }
    
    0 讨论(0)
提交回复
热议问题