2012-02-16 13 views
5

、私は次のコード抽象クラス、コードの重複を避ける方法は?私は基本クラスから継承これらのスバとSUBBクラスを持っている

internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public abstract void Invoke(string message); 
} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     Time = DateTime.Now; 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void Invoke(string message) 
    { 
     Time = DateTime.Now; 
     // Do B 
    } 
} 

を持って、私はそれを時間を設定している自己を繰り返し、への道があることを、コードを持っていることがわかります時間の設定を基本クラスに移動しますか?

答えて

3

多くの解決策があります。

これは、このプロパティセットをいつ設定するかによって異なります。

すぐにご希望の場合は、Baseクラスのコンストラクタでこれを行うことができます。

internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public abstract void Invoke(string message); 

    public Base() 
    { 
     Time = DateTime.Now; 
    } 
} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void Invoke(string message) 
    { 
     // Do B 
    } 
} 
+0

この場合、SetTimeを保護する必要があります。 – PVitt

2

代わりに仮想メソッドを使用します。

internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public virtual void Invoke(string message) { 
     Time = DateTime.Now; 
    } 
} 

internal class SubA : Base 
{ 
} 

internal class SubB : Base 
{ 
} 

をあなたはまだあなたが異なる実装をしたいサブクラスでメソッドをオーバーライドすることができます。

5

あなたはこのような何かを行うことができます:

internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public void Invoke(string message){ 
     Time = DateTime.Now; 
     this.InvokeInternal(message); 
    } 
    protected abstract void InvokeInternal(string message); 
} 

internal class SubA : Base 
{ 
    protected override void InvokeInternal(string message) 
    { 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    protected override void InvokeInternal(string message) 
    { 
     // Do B 
    } 
} 
+1

+1。まさに私がやること。 – Jehof

2
internal abstract class Base 
{ 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public virtual void Invoke(string message) 
    { 
     Time = DateTime.Now; 
    } 

} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     base.Invoke(message); 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void Invoke(string message) 
    { 
     base.Invoke(message); 
     // Do B 
    } 
} 
+0

チェックベースの参照:http://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx –

0

はすでに答えがたくさんあります。代替(そして忍者のアプローチ)アプローチとして、Lambda式をメソッドのプロパティで使用することをお勧めします。

あなたの場合、

public class Base 
    { 
    public DateTime Time; 
    public string Message; 
    public string Log; 
    public Action<string> Invoke { get; set; } 

    public Base() 
    { 
     this.Invoke = InvokeDefault; 
    } 

    private void InvokeDefault(string message) 
    { 
     Time = DateTime.Now; 
    } 
    } 

このようにして、baseクラスにデフォルトの動作を提供します。 ラムダ表現では次のように異なるInvokeメソッドでインスタンスを作成することができます。..

var myInstance= new Base 
    { 
    Invoke =() => { Time = DateTime.Now.AddDays(7); } 
    }; 

invokeメソッドだけBaseクラスのこのインスタンスのために上書きされます。これにより、柔軟性が増し、不要なサブクラス化が回避されます。

詳細はawesome post from Patrick Steeleをご確認ください。

0

コード契約の厳格さに応じて2つの実用的なオプションがあります。

ロジックを仮想メソッドに移動し、そのように選択した場合、子タイプが動作をオーバーロードすることを許可できます。

internal abstract class Base 
{ 
    ... 
    public virtual void Invoke(string message) 
    { 
     Time = DateTime.Now; 
    } 
} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     base.Invoke(message); 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void Invoke(string message) 
    { 
     base.Invoke(message); 
     // Do B 
    } 
} 

ただし、これにより、派生型が基本メソッドをまったく呼び出さないようにすることができます。

基本的な機能が呼び出されないと、あなたが期待される動作をより確実にしたい場合は、それは壊滅的だ場合は、基本法の中間に注入点を提供することで、より強力な契約を作りたいかもしれません:

internal abstract class Base 
{ 
    ... 
    public void Invoke(string message) 
    { 
     Time = DateTime.Now; 
     this.InvokeCore(message); 
    } 

    protected abstract void InvokeCore(string message); 
} 

internal class SubA : Base 
{ 
    public override void Invoke(string message) 
    { 
     // Do A 
    } 
} 

internal class SubB : Base 
{ 
    public override void InvokeCore(string message) 
    { 
     // Do B 
    } 
} 
関連する問題