2009-04-15 8 views
7

私は以下のように簡略化されたBaseから派生したタイプはほとんどありません。"base"コンストラクタまたは "this"コンストラクタのオーバーロード?

コンストラクタのオーバーロード時に、基本クラスのコンストラクタを使用するか、thisコンストラクタを使用するかはわかりません。
ConcreteB過負荷が最初の2つのオーバーロードのため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"を常に呼び出します。だから "これ"が何もしない場合でも、それは "ベース"に落ちるでしょう –

1

ご提供いただいたものから、問題はありません。実際には、現在のクラスのコンストラクタが基底クラスに含まれていない場合、または基底クラスに含まれていない現在のクラスコンストラクタに実行するコードがある場合は、thisを使用します。

2

一般に、私は「ベース」ではなく「this」と呼んでいます。後でクラスを展開すると、おそらくコードを再利用するでしょう。

0

コードパスの複雑さを軽減するために、私は通常、ちょうど1つのbase()コンストラクタコール(ConcreteBの場合)を試しています。このようにして、基本クラスの初期化は常に同じ方法で行われることがわかります。

ただし、上書きするクラスによっては、これが不可能な場合や、不要な複雑さを追加する場合があります。これは、ISerializableを実装するときのような特殊なコンストラクタパターンに対しても当てはまります。

2

混在しても問題ありません。最終的にthis(...)コンストラクタを使用すると、が最終的にになり、base(...)が最初に呼び出されます。必要に応じてロジックを再利用することは理にかなっています。

すべてのコンストラクタは(多分プライベート)共通と呼ばれるように、あなたはそれを手配することができbase(...)まで呼び出すだけですthis(...)コンストラクタ - それはかどうかによって異なります。そうすることが有用であり、B :1つのbase(...) ctorがあるかどうか。

0

Baseクラスのコンストラクタがなぜオーバーロードされているのか、もう一度質問してください。この1つは十分です:あなたは、あなたがすでにデフォルトコンストラクタを持っているので、あなたの例ではそうではありませんどのインスタンス化したときに特定の値を持っているいずれかのフィールドを必要としない限り、

protected Base() 

同じサブクラスのために行きます。

コンストラクタは、オブジェクトのインスタンスを正しい状態にする必要があります。

関連する問題