2011-10-30 82 views
1

我想组织一个场景图。 我一般类场景节点:C#访问受保护的领域

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

智能感知说node.parent和其他受保护领域无法从SceneNodeContainer访问。我该如何克服这一点?

回答

7

你不能,因为这样保护的作品 - 它仅允许访问这是众所周知的是孩子的类型(或子类型)的对象的保护领域。因此,如果node是一个SceneNodeContainer变量,你必须进入领域 - 但除此之外,你不知道。

从C#4规范的3.5.3节:

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

(顺便说一句,我个人避免保护领域的反正。我做不恒定的私人领域在几乎所有情况下)。

+0

“我几乎在所有情况下都使非常量字段保密。” - 你认为这是一个糟糕的设计或个人喜好的症状吗? –

+0

@威廉:设计。字段是一个实现细节,不应该是公开的API的一部分 –

+0

好吧,因为它通常发生在我身上,解决方案出现在发布这个问题后。 SceneNode类现在将具有AddAfter和AddBefore方法,而SceneNodeContainer将有一个空的SceneNode作为第一个子元素(所以它就像头部列表)。我同意隐藏领域。我只在基本结构中打开它们。 – lazychaser

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

'protected internal'允许访问同一个程序集*和*所有子类中的* all *类 - 但是其他程序集的子类只会得到与被保护一样的访问权限......所以,您的建议有效相当于使其内部。 (因此,这就是为什么它在这里工作。)就我个人而言,我会尝试坚持私人领域。 –

+0

@JonSkeet明白了。谢谢 – Damith