2011-12-25 4 views
3

まずタイトルを残念に思うが、私は自分の問題を正確に記述する方法を知らない。私はそれがコードを通してよりよく説明されることを願っています。マイファクタをリファクタリングする:派生クラスでキャストすることを避ける

public abstract class AB { 
    public MyModel Model; 
} 

public class A : AB { 
    public A() { 
    Model = new MyModelA(); 
    } 

    public void AMethod() { 
    var model = (MyModelA) model; // I have to do this all place 
    } 

    public void AnotherMethod() { 
    var model = (MyModelA) model; // same here 
    model.NewInt = 123; 
    } 
} 

public abstract class MyModel { 

} 

public class MyModelA : MyModel { 
    // new properties 
    public int NewInt {get;set;} 
} 

派生クラスから新しいプロパティを使用するために、私はキャストをしなければならないが、私はすべての場所の上にそれを同じ時間を使用する必要がある場合、それは醜いです、コードを見てみましょう。

私が思う方法は、別のプロパティ:public MyModelA _tmpを宣言してから、それをコンストラクタ_tmp = (MyModelA) Modelにキャストし、Modelの代わりに使用します。

他にもこれを行う方法はありますか? ありがとう!

答えて

10

あなたは、基本クラスは一般的なことができます:

public abstract class ServiceBase<TModel> where TModel : new() { 
    protected ServiceBase() { Model = new TModel(); } 
    public TModel Model { get; private set; } 
} 

public class AService : ServiceBase<MyModelA> { 
    ... 
} 
+1

抽象クラスには 'protected'コンストラクタが必要です。 – bobbymcr

+1

あなたは正しいです。私はそれを忘れてしまった。一定。 – SLaks

+0

これは、TModelがAServiceに渡されたという事実に対処するために、どのように役立ちますか? – Nicolas78

1

あなたは派生クラスで自分のモデルの参照を維持することができます。

public abstract class AB { 
    public MyModel Model; 
} 

public class A : AB { 
     MyModel MyModel; 

    public A() { 
      MyModel = new MyModelA(); 
      Model = MyModel; 
    } 

    public void AMethod() { 
      //just use MyModel 
    } 

    public void AnotherMethod() { 
    MyModel.NewInt = 123; 
    } 
} 

public abstract class MyModel { 

} 

public class MyModelA : MyModel { 
    // new properties 
    public int NewInt {get;set;} 
} 
+0

yeaしかし、私は最初に新しいフィールドを導入していない理由があると思います(つまり、MyModelAはまだMaModelとしての役割を果たしています)。 – Nicolas78

+0

これは私のソリューションのクリーナーバージョンです。キャストは同じ考えです。 – nXqd

+0

はい、キャスティングを避ける方法を尋ねました:) – ivowiblo

0

_tmpと解決策は、そのマニュアルキャストを書くことであなたをのRID常に、しかし、奇妙なオブジェクトデザインの問題が残っています。

私はあなたのNewIntが、MyModelにも存在していた何らかの機能を実行していると思います(そうしないと、新しいクラスを作成する方が良いでしょう)。私はMyModelAが何も新しいものを公開する必要がないようにその機能をカプセル化できないのだろうかと思います。これは、そのような一般化を可能にするためにABの定義を変更することを意味するかもしれない。

答えは、ドメインを理解することなく構文的にもOOPパターンでも簡単に見つかりません。おそらくあなたはそれについていくつかの詳細を提供することができます。

+0

OkよくSLaksの答えは、非常にきれいに私の最後の答えが間違っている可能性がありますので、ドメインアグノスティックな答えを提供します。それでも、MyModelAに新しいパブリックプロパティを公開する必要がある理由を検討する価値があるかもしれません – Nicolas78

関連する問題