【问题标题】:Can't access protected member of the same base class无法访问同一基类的受保护成员
【发布时间】:2014-02-22 19:14:35
【问题描述】:

我有这样的事情:

class Node
{
    protected Node Parent
    {
        get; private set;
    }
}

class NodeDerived : Node
{
    void SomeMethod()
    {
        Node parentIterator = this.Parent;

        while (parentIterator != null)
        {
            // ... some logic

            parentIterator = parentIterator.Parent; // Here's the error
        }
    }
}

但由于某些奇怪的原因,我无法访问parentIterator.Parent 属性:

error CS1540: Cannot access protected member `Node.Parent' via a qualifier of type `Node'. The qualifier must be of type `NodeChild' or derived from it

为什么会这样?对了,我还发现虽然我可以访问this.Parent,但我不能访问((Node) this).Parent。

【问题讨论】:

标签: c# mono access-modifiers


【解决方案1】:

来自 C# 5 规范,第 3.5.3 节:

如果在声明它的类的程序文本之外访问受保护的实例成员,并且在声明它的程序的程序文本之外访问受保护的内部实例成员时,必须进行访问在从声明它的类派生的类声明中。此外,访问需要通过派生类类型的实例或由它构造的类类型进行。此限制可防止一个派生类访问其他派生类的受保护成员,即使这些成员是从同一基类继承的。

所以你可以访问任何NodeDerived 对象的Parent 属性:

NodeDerived derivedNode = ...;
Node parent = derivedNode.Parent;

...但是您不能访问不是NodeDerived 或子类的节点类型的Parent 属性。

使用this.Parent 有效,因为this 的编译时类型是NodeDerived。

我怀疑您希望公开您的 Parent 属性 - 假设您希望此代码与 NodeDerived 以外的节点一起使用。

【讨论】:

  • 这就是我修复它的方式,是的。感谢您的解释!我使用的是 Mono 2.6,所以我没有查看 C# 5 文档,但我认为它在这方面没有改变。
  • @golergka:不,受保护的访问从 C# 1.0 开始就以这种方式工作。
  • 顺便说一句,虽然这个问题已经得到了明确的回答,但你知道他们为什么要设计成这样吗?
  • @golergka:我相信这个想法是几个类可能有相同的要求,但不想让彼此访问。我不能说我自己非常使用protected。顺便说一句,Java 的工作方式几乎相同。
猜你喜欢
  • 2014-01-26
  • 2019-01-20
  • 2016-10-01
  • 2022-01-06
  • 2012-11-20
  • 1970-01-01
  • 2012-08-29
  • 2016-04-07
相关资源
最近更新 更多