2009-08-04 2 views
5

기본 클래스에서이 속성이 있습니다 :재정의 된 속성에 대해 접근자를 추가 할 수없는 이유는 무엇입니까?

public virtual string Text 
{ 
    get { return text; } 
} 

나는 그것을 무시하고 다른 텍스트를 반환하고 싶지만 텍스트를 설정할 수 있기를 바랍니다. 그래서

public override string Text 
{ 
    get { return differentText; } 
    set { differentText = value; } 
} 

그러나 이것은 작동하지 않습니다. set 아래에 빨간색 구불 구불 한 점이 있는데, set accessor가 없기 때문에 재정의 할 수 없다는 의미입니다. 왜 이것이 문제입니까? 어떻게해야합니까?

+0

나는 동일 할 싶습니다. 가능해야합니다. –

+0

가능하지만 "중산층"이 필요합니다. 또한 여러 상황에서 좋은 아이디어는 아니지만, 예를 들어 추상 속성을 무시할 때와 같은 몇 가지 예외가 있습니다. Base :'public abstract string Text {get; }'. 중간 (상속) :'protected internal string text;''public sealed override string Text {get {return text; }}'. 하위 (상속 중간) :'public new string Text {get {return text; } set {text = value; }}'. 보호 된 내부 수정 자 및 봉합 된 덮어 쓰기는 캡슐화가 어셈블리 외부에서 손상되지 않도록합니다. – AnorZaken

+0

@AnorZaken : 그것은 무시하지 않습니다. 그것은 그림자입니다. 중급 클래스도 필요하지 않습니다. – Guffa

답변

3

존재하지 않는 일련의 메소드를 오버라이드 (override)하려고되지만, 단어 "재정의" 선언에서 컴파일러는 기본 클래스에서 동일한 서명을 가진 메소드를 찾습니다. 그 방법을 찾을 수 없으므로 세트를 만들 수 없습니다.

ArsenMkrt에 따르면 기본 선언에 보호 집합을 포함하도록 변경할 수 있다고합니다. 이렇게하면 재정의 할 수 있지만 여전히 서명을 변경할 수 없으므로 하위 클래스의이 메소드를 public으로 승격 할 수 없으므로 게시 한 코드는 작동하지 않습니다.

아무 것도하지 않는 기본 클래스에 공용 가상 세트 메소드를 추가해야합니다 (또는 호출하려고 시도해도 예외가 발생 함).하지만 클래스의 사용자가 기대하는 것과 상반됩니다

///<summary> 
///Get the Text value of the object 
///NOTE: Setting the value is not supported by this class but may be supported by child classes 
///</summary> 
public virtual string Text 
{ 
    get { return text; } 
    set { } 
} 

//using the class 

BaseClass.Text = "Wibble"; 
if (BaseClass.Text == "Wibble") 
{ 
    //Won't get here (unless the default value is "Wibble") 
} 

그렇지 않으면 별도의 방법으로 세트를 선언 :이 작업을 수행 할 경우 동작은 (그리고 나는 그것을 권장하지 않습니다)가 너무 잘 사용자가 그것을 놓칠 수없는 문서화되어 있는지 확인 그럴하기 귀하의 자녀 수업 :

public override string Text 
{ 
    get { return differentText; } 
} 

public void SetText(string value) 
{ 
    differentText = value; 
} 
+0

나는 그것을 좋아하지 않아,하지만 나는 별도의 SetText 방법이나 뭔가를 가지고 라인을 따라 뭔가를해야 할 것 같아요 ... 감사합니다 :) – Svish

+0

글쎄, 또한 수 건축상의 문제가된다. 사용자가 기본 클래스에서 텍스트 값을 설정할 수없는 이유는 무엇입니까? 두 클래스 모두에서 * 실제로 * 동일한 속성입니까? 이와 같은 패턴이 필요한 일반적인 요구 사항 인 것 같습니다. –

+0

글쎄, 그것은 여러 종류의 값을 보유하고있는 다양한 Parameter 클래스입니다. 그리고 나는 그들 모두가 사용자가 읽을 수있는 텍스트 값으로 그들 자신을 표현할 수 있기를 바란다. 하지만 모든 매개 변수가 텍스트로 설정되는 것을 원하지 않습니다 (구문 분석은 인쇄보다 훨씬 성가심입니다). 예를 들어, 날짜를 인쇄 할 날짜 매개 변수를 설정할 수는 있지만, 설정은 datepicker로 끝나기 때문에 텍스트를 통해 날짜를 설정할 필요는 없습니다. – Svish

3
public virtual string Text 
{ 
    get { return text; } 
    protected set {} 
} 

변경 기본 클래스의 속성은, 당신은 당신이 공공 set 메소드를 작성하는 코드의 두 번째 블록에서

+0

보호 된 설정자를 자식 클래스의 공용 설정자로 재정의 할 수 없습니다. – Guffa

+0

흠, 동의 .... :) –

2

당신이 파산하기 때문에 문제가됩니다. 캡슐화. 당신은 무언가를 무효화하고 더 접근하기 쉽게 만들 수 없다. 그것은 창 밖으로 캡슐화에 대한 모든 것을 던질 것이다.

귀하가 실제로 원래 가치가 아닌 것을 드러내지 만 귀하의 경우에도 마찬가지입니다.

시도한 것을 정확하게 수행 할 방법이 없습니다. 기본 클래스에 setter를 만들거나 새로운 값을 설정하는 다른 방법을 사용해야합니다.

public new string Text 
{ 
    get { return differentText; } 
    set { differentText = value; } 
} 

그러나이 유형의 변수를 통해 오브젝트를 조작 할 때 속성에만 사용됩니다 경우에

아닌 기본 유형

+0

하위 클래스는 캡슐화가 이미 기본 클래스에서 이미 손상된 경우를 제외하고는 수행 할 수 없으므로 캡슐화를 중단 할 수 없습니다. 아이가 재산의 후원자 필드에 액세스 할 수 없도록되어 있음). 또한 기본 클래스는 속성을 가상으로 선언 했으므로 속성을 변경하는 것이 가능하다는 것을 의미합니다. 속성/메서드가 가상 일 경우에는 아무 것도 실행되지 않습니다. (물론 문서의 내용을 고수하는 한) 가상적이어야하는지 아니면 기본 클래스의 캡슐화를 깨뜨릴 지 여부는 진정한 질문이며, 그에 따라 다릅니다. – AnorZaken

+0

@AnorZaken : 그게 무슨 소리 죠? 회원이 가상이라는 이유만으로 원하는대로 재정의 할 수있는 것은 아닙니다. – Guffa

2

당신은 기본 클래스의 속성을 숨길 수 하위 유형을 사용할 때 더 많은 기능을 공개하려고합니다. 재정의하고 싶지 않고 그림자처럼 보이기를 원하는 것처럼 들립니다. new 키워드를 사용하여 읽기/쓰기 가능 속성 아래에 읽기 전용 텍스트 속성을 숨 깁니다.기본 클래스에서

:

protected string text; 
public string Text 
{ 
    get { return text; } 
} 

파생 클래스에서 :

new public string Text 
{ 
    get { return text; } 
    set { text = value; } 
} 
2

:

+0

동시에 그림자를 칠하고 무시할 수 있습니까? – Svish

+0

아니, 그들은 다른 것을 의미합니다. 그림자 또는 재정의는 기본 유형으로 변환 한 후에도 Text의 비헤이비어가 영향을 받는지 여부를 결정합니다. 더 자세한 설명을 보려면이 질문을 확인하십시오. http://stackoverflow.com/questions/673779/what-is-shadowing –