2011-10-30 3 views
1

장면 그래프를 구성하고 싶습니다. 나는 일반 클래스 SceneNode에 있습니다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

보호 된 작동 방식으로 인해 하위 유형 (또는 하위 유형)으로 알려진 객체의 보호 된 필드에만 액세스 할 수 있습니다. 따라서 nodeSceneNodeContainer 인 경우 필드에 액세스 할 수 있습니다. 그렇지 않으면 필드에 액세스 할 수 있습니다. 는 C# 4 사양의 섹션 3.5.3에서

는 :

보호 인스턴스 부재가 선언 된 클래스의 프로그램 텍스트 외부 액세스

및 보호 내부 인스턴스 부재가 액세스 될 때 프로그램이 선언 된 프로그램의 텍스트 밖에서는 선언 된 클래스에서 파생 된 클래스 선언 내에서 액세스가 이루어져야합니다. 게다가, 접근은 그 파생 된 클래스 타입의 인스턴스 또는 그것으로부터 생성 된 클래스 타입을 통해 일어날 필요가있다. 이 제한 사항은 멤버가 동일한 기본 클래스에서 상속 된 경우에도 하나의 파생 클래스가 다른 파생 클래스의 보호 된 멤버에 액세스하지 못하게합니다.

(여담으로, 개인적으로 어쨌든 보호 필드를 피할 것. 나는 개인 거의 모든 경우에 상수가 아닌 필드를 확인하십시오.)

+0

"거의 모든 경우에 비 상수 필드를 비공개로 설정합니다." - 디자인이 좋지 않거나 개인적인 취향의 증상이라고 생각하십니까? –

+0

@ 윌리엄 : 디자인. 필드는 구현 세부 사항이며 노출 된 API의 일부가 아니어야합니다. –

+0

일반적으로 나와 함께 발생하므로 솔루션은이 질문을 게시 한 직후에 나타납니다. SceneNode 클래스는 이제 AddAfter와 AddBefore 메소드를 가질 것이고 SceneNodeContainer는 첫 번째 자식으로 빈 SceneNode를 갖게 될 것입니다 (그래서 그것은 headed list와 같습니다). 그리고 나는 들판을 숨기는 것에 동의합니다. 나는 그것들을 기본 구조체에서만 열어 둔다. – lazychaser

2

대신 protected의 사용 protected internal을 다음의 하위 클래스에서 액세스 할 수있는 같은 어셈블리.

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'은 같은 어셈블리 내의 * 모든 * 클래스에 대한 액세스를 제공합니다 * 그리고 모든 서브 클래스 - 그러나 다른 어셈블리의 서브 클래스는 보호 된 것처럼 동일한 액세스를 얻습니다 ... 그래서 효과적으로 당신의 제안은 다소 있습니다 내부적으로 만드는 것과 같습니다. (그 점에서 그것이 그것이 여기에서 작동하는 이유입니다.) 개인적으로 나는 사적인 밭에 충실하려고 노력할 것입니다. –

+0

@JonSkeet 알아 들었어. 감사 – Damith

관련 문제