重构我的代码:避免在派生类中进行强制转换

时间:2011-12-25 18:39:16

标签: c# refactoring

首先,我对标题感到遗憾,我不知道如何准确描述我的问题。我希望通过代码更好地解释。

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并使用它而不是模型。

还有其他适当的方法吗? 谢谢!

3 个答案:

答案 0 :(得分: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 :(得分: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;}
}

答案 2 :(得分:0)

使用_tmp的解决方案使您不得不一直编写该手册,但仍存在奇怪的对象设计问题。

我猜你的NewInt会在那里执行MyModel中也存在的某种功能(否则你最好先为它创建一个新类)。我想知道你是否不能以MyModelA不必暴露任何新内容的方式封装该功能。这可能意味着改变AB的定义以便允许这样的概括。

我相信答案在没有理解域的情况下,既不是语法也不容易在OOP模式中找到。也许你可以提供一些细节。