Tzu ng
Tzu ng

Reputation: 9244

Refactor my code : Avoiding casting in derived class

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 !

Upvotes: 3

Views: 527

Answers (3)

Nicolas78
Nicolas78

Reputation: 5144

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.

Upvotes: 0

SLaks
SLaks

Reputation: 887797

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> {
    ...
}

Upvotes: 10

Ivo
Ivo

Reputation: 8362

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

Upvotes: 1

Related Questions