2009-04-15 7 views
7

다음과 같이 간체 Base에서 파생 된 유형은 거의 없습니다.오버로드 "기본"생성자 또는 "이"생성자?

생성자를 오버로드 할 때 기본 클래스의 생성자를 사용할지 또는 this 생성자를 사용할지 확실하지 않습니다.
ConcreteB 과부하 처음 두 과부하 this 사용시

ConcreteA 과부하 생성자 순전히 base 생성자를 사용.

생성자를 오버로드하는 더 좋은 방법은 무엇입니까?

public abstract class Base 
{ 
    public string Name { get; set; } 
    public int? Age { get; set; } 

    protected Base() : this(string.Empty) {} 
    protected Base(string name) : this(name, null) {} 
    protected Base(string name, int? age) 
    { 
     Name = name; 
     Age = age; 
    } 
} 

public class ConcreteA : Base 
{ 
    public ConcreteA(){} 
    public ConcreteA(string name) : base(name) {} 
    public ConcreteA(string name, int? age) : base(name, age) 
    { 
    } 
} 

public class ConcreteB : Base 
{ 
    public ConcreteB() : this(string.Empty, null){} 
    public ConcreteB(string name): this(name, null){} 
    public ConcreteB(string name, int? age) : base(name, age) 
    { 
    } 
} 

[편집] 그것은 이안 퀴 글리는 answer 이해가 듯 자신에 제시된 것을 보이는 . 유효성 검사기를 초기화하는 호출이있는 경우 ConcreteA(string)은 다음 경우에 유효성 검사기를 초기화하지 않습니다.

public class ConcreteA : Base 
{ 
    public ConcreteA(){} 
    public ConcreteA(string name) : base(name) {} 
    public ConcreteA(string name, int? age) : base(name, age) 
    { 
     InitializeValidators(); 
    } 
    private void InitializeValidators() {} 
} 

답변

5

입니다. 왜냐하면 ConcreteB (string, int?)에 코드를 두는 경우 문자열 전용 생성자가이를 호출하기를 원하기 때문입니다.

+0

이것은 콘크리트 생성자에서 다른 초기화 작업을 수행해야하는 경우에 의미가있는 것처럼 보입니다. – Sung

+0

예, "this"는 하루가 끝날 때 항상 "base"를 호출합니다. 그래서 "this"가 아무것도하지 않더라도, "base" –

1

귀하가 제공 한 것으로부터 중요하지 않습니다. 현재 클래스에 기본 클래스의 일부가 아닌 생성자가 있거나 기본 클래스에 포함되지 않은 코드를 실행하려는 현재 클래스 생성자에있는 경우에만 this을 사용하려고합니다. .

2

일반적으로 '기본'이 아닌 '이'라고 말하고 싶습니다. 나중에 클래스를 확장하면 코드를 재사용 할 수 있습니다.

0

코드 경로의 복잡성을 줄이기 위해 나는 보통 정확하게 하나의 base() 생성자 호출 (ConcreteB 경우)을 사용하려고합니다. 이렇게하면 기본 클래스의 초기화가 항상 같은 방식으로 수행된다는 것을 알 수 있습니다.

그러나 재정의 한 클래스에 따라 이는 불가능하거나 불필요한 복잡성을 추가 할 수 있습니다. 이는 ISerializable을 구현할 때와 같은 특수한 생성자 패턴에도 적용됩니다.

2

섞어서 일치시키는 것이 좋습니다. 궁극적으로 this(...) 생성자를 사용하면 이 결국이되어 base(...)이 먼저 호출됩니다. 필요한 경우 논리를 다시 사용하는 것이 좋습니다.

base(...)으로 부르는 유일한 생성자 인 공통 (아마도 개인) this(...) 생성자를 호출 할 수 있도록 정렬 할 수 있습니다. 그러나 이렇게하는 것이 유용한 지 여부와 b에 따라 다릅니다. : 당신을 보낼 수있는 단일 base(...) ctor가 있는지 여부.

0

왜 기본 클래스에서 생성자가 오버로드되는지 다시 확인하십시오. 이 사람은 충분하다 : 당신이 당신의 예에서 이미 기본 생성자를 갖고 있기 때문에 그렇지 않은하는 인스턴스화 할 때 특정 값을 가지도록하거나 필드를 필요로하지 않는

protected Base() 

같은 서브 클래스에 간다.

모든 생성자는 개체의 인스턴스를 올바른 상태로 놓아야 함을 기억하십시오.