C#访问受保护的字段

时间:2011-10-30 09:54:05

标签: c# inheritance

我想组织一个场景图。 我有一般类SceneNode:

public class SceneNode
{
    protected SceneNode prev, next;
    protected SceneNodeContainer parent;

    public SceneNode Parent { get { return parent; } }
    public SceneNode PreviousNode { get { return prev; } }
    public SceneNode NextNode { get { return next; } }
}

我也有类SceneNodeContainer,它是这样的:

public class SceneNodeContainer : SceneNode
{
    SceneNode firstChild, lastChild;

    public SceneNode FirstChild { get { return firstChild; } }
    public SceneNode LastChild { get { return lastChild; } }

    public void Add(SceneNode node)
    {
        Debug.Assert(node != null);
        Debug.Assert(node.parent == null);

        node.parent = this;
        node.prev = lastChild;
        node.next = null;

        if (lastChild == null)
        {
            lastChild = node;
            firstChild = lastChild;
        }
        else
        {
            lastChild.next = node;
            lastChild = node;
        }
    }

    public void Remove(SceneNode node)
    {
        Debug.Assert(node != null);
        Debug.Assert(node.parent == this);

        //unlink node
        if (node.next != null)
            node.next.prev = node.prev;

        if (node.prev != null)
            node.prev.next = node.next;

        if (node == firstChild)
            firstChild = node.next;

        if (node == lastChild)
            lastChild = node.prev;

        node.parent = null;
        node.next = null;
        node.prev = null;
    }
}

IntelliSense表示无法从SceneNodeContainer访问node.parent和其他受保护字段。我怎么能克服这个?

2 个答案:

答案 0 :(得分:7)

由于受保护的方式,它不能允许访问已知为子类型(或子类型)的对象的受保护字段。因此,如果nodeSceneNodeContainer变量,则您可以访问这些字段 - 但是否则,您没有。

来自C#4规范的第3.5.3节:

  

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

(顺便说一下,无论如何,我个人都会避开受保护的字段。我几乎在所有情况下都将非常量字段设为私有。)

答案 1 :(得分:2)

使用protected internal代替protected,然后您可以从同一个程序集的子类访问。

public class SceneNode
{
    protected internal SceneNode prev, next;
    protected internal SceneNodeContainer parent;

    public SceneNode Parent { get { return parent; } }
    public SceneNode PreviousNode { get { return prev; } }
    public SceneNode NextNode { get { return next; } }
}