3

Firstly, I feel sorry about the title, I do not know how to describe my problem exactly. I hope it will be better explained through the code.

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;}
}

Take a look at the code, in order to use new properties from derived class, I have to do a cast but it is ugly when I have to use it same time all over places.

The method I think is declare another property: public MyModelA _tmp then I cast it in the constructor _tmp = (MyModelA) Model and use it instead of Model.

Are there any other appropriate ways to do this ? Thanks !

Dzung Nguyen
  • 9,152
  • 14
  • 65
  • 104

3 Answers3

10

You can make the base class generic:

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

public class AService : ServiceBase<MyModelA> {
    ...
}
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
1

You can maintain your Model reference in the derived class:

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;}
}
Ivo
  • 8,172
  • 5
  • 27
  • 42
0

The solution with _tmp rids you of having to write that manual cast all the time, but the problem of a strange object design remains.

I would guess your NewInt is there to perform some sort of functionality that was also present in MyModel (otherwise you'd be better off creating a new class for that to begin with). I'm wondering if you can't encapsulate that functionality in a way that MyModelA does not have to expose anything new. This may mean changing the definition of AB in order to allow for such generalizations.

The answer, I believe, is neither syntactic nor easily found in a OOP pattern without understanding the domain. Maybe you can provide some details on that.

Nicolas78
  • 5,124
  • 1
  • 23
  • 41
  • Ok well SLaks answer pretty nicely provides a domain-agnostic answer so my last answer may be wrong. Still, it may be worth looking into why you have to expose a new public property in MyModelA – Nicolas78 Dec 25 '11 at 18:54