2011-10-30 151 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