访问受保护的字段

本文关键字:字段 受保护 访问 | 更新日期: 2023-09-27 18:12:51

我想组织一个场景图。我有一个通用类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; } }
}

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

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

智能感知表示该节点。parent和其他受保护的字段不能从scenenecontainer中访问。我该如何克服?

访问受保护的字段

不能,因为protected的工作方式-它只允许访问已知为子类型(或子类型)的对象的受保护字段。因此,如果nodeSceneNodeContainer变量,则可以访问字段-否则,则不能。

来自c# 4规范第3.5.3节:

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

(顺便说一句,我个人会避免使用受保护的字段。我几乎在所有情况下都将非常量字段设为私有)

使用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; } }
}