有没有办法从派生类型到达另一个对象的`protected`成员?

时间:2008-12-05 16:58:02

标签: c# oop

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)
    }
}

有没有办法从没有反射的扩展类型获取类型参数的受保护属性?由于扩展类通过其基类型知道属性,因此如果可能的话,它将是有意义的。

7 个答案:

答案 0 :(得分:16)

上次我遇到类似问题时,我使用了向基础添加受保护静态方法的解决方案:

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);
    }
}

答案 1 :(得分:11)

不,你不能这样做。

您只能访问访问类型(或从中派生)的对象的受保护成员。在这里,我们不知道参数是MyType类型还是SomeOtherCompletelyDifferentType。

编辑:C#3.0规范的相关位是第3.5.3节:

  

受保护的实例成员是   在程序文本之外访问   声明它的类,和   当受保护的内部实例时   会员在该计划之外访问   它所在的程序的文本   声明,必须进行访问   在一个类声明中   源自它所在的类   声明。此外,访问是   要求通过一个   该派生类类型的实例或   从它构造的类类型。这个   限制阻止一个派生类   从访问受保护的成员   其他派生类,即使是   成员继承自同一个   基类。

答案 2 :(得分:5)

有一个很好的理由你不能这样做。假设某人写道:

class Other : MyBase { }

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

如果该语言允许您提出要求,则可以通过修改Other的值来违反假定的PropertyOfBase不变量。

答案 3 :(得分:2)

我认为您应该问自己是否有更好的方法来做您想做的事情。您希望PropertyOfBase在MyType.MyMethod()的上下文中充当公共,但要在所有其他情况下受到保护。为什么呢?

答案 4 :(得分:1)

受保护的属性只能由派生类的实例访问,而不能访问派生类的实例。

存在差异并且确实有意义,受保护的成员不应该将其值放弃到任何其他实例,甚至是从相同类型派生的实例。

(编辑,让自己有点舌头!)

答案 5 :(得分:0)

当您从MyBase继承时,您可以使用“base”关键字访问标记为“protected”的所有字段/属性/方法。

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

public class MyType : MyBase
{
    void MyMethod()
    {
        object p =  base.PropertyOfBase;
    }
}

答案 6 :(得分:0)

您还可以将MyType声明为MyBase的嵌套类(而不是继承),这样您可以在将MyBase类作为参数发送时访问私有/受保护成员

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

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

要创建MyType实例,只需使用

var t = new MyBase.MyType();
t.MyMethod(new MyBase());