2013-11-28 6 views
2

이 같은 클래스가 :파생 클래스가 기본 클래스에서 보호 된 getter에 액세스 할 수없는 이유는 무엇입니까?

public class Base 
{ 
    public Base(string name) 
    { 
     this.Name = name; 
    } 

    public string Name { get; set; } 
    public string PrettyName 
    { 
     get { return Prettify(Name); } 
    } 
} 

을 나는 그것에서 파생 :

public class Derived : Base 
{ 
    public Derived(Base b) : base(b.Name) { } 
} 

Name 속성을 액세스 할 수 없습니다한다 논리 이름은 PrettyName에 의해서만 액세스되어야합니다. 나는이

public string Name { protected get; set; } 

그러나납니다 : : 왜 그

Cannot access protected member 'Name' via a qualifier of type 'Base'; the qualifier must be of type 'Derived' (or derived from it) 

이다 그래서 나는이 같은 속성을 만들 것이라고 생각? getter는 기본 클래스와 모든 하위 클래스에 노출되어야합니다. 내가 여기서 뭔가 잘못 됐어?

답변

5

getter는 기본 클래스와 모든 하위 클래스에 노출되어야합니다.

아니오, 그렇지 않습니다. 이것은 자동으로 구현 된 속성의 문제가 아닙니다. 이는 protected의 의미입니다.

하위 클래스 내의 보호 된 멤버에 대한 액세스는 해당 하위 클래스 (또는 그 이상의 하위 클래스)의 인스턴스를 통과해야합니다. Base.Name을 임의로 사용하면BaseDerived에 사용할 수 없습니다.

protected 인스턴스 멤버는 프로그램이 선언 된 클래스의 텍스트, 때 외부에 액세스 할 때 protected internal 인스턴스 멤버가 외부에서 액세스 할 수 있습니다 :는 C# 사양의 섹션 3.5.3에서

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

간단한 해결책이 Base에 생성자를 오버로드하는 것입니다 : Derived에서 다음

protected Base(Base b) : this(b.Name) 
{ 
} 

가 : 그 시점에서

public Derived(Base b) : base(b) { } 

, 당신은 Name, 개인 세터도 만들 수 있습니다 - 또는 더 나은 아직 완전하게 읽기 전용으로 만드십시오 :

private readonly string name; 
public string Name { get { return name; } } 
0

이것은 파생 된 생성자를 만드는 흥미로운 방법입니다. 왜 안되는가? :

public class Derived : Base 
{ 
    public Derived(string name) : base(name) 
    { } 

    public void Test() 
    { 
     //here, it's perfectly ok to access the protected Name. 
    } 
} 
+0

왜냐하면 예제 코드가 단순하고 실제 코드로 달성하고자하는 것은 새로운 객체에 'b'의 모든 속성 (단지 이름 이상)이 복사되기 때문이다. –