【问题标题】:Refactor my code : Avoiding casting in derived class重构我的代码:避免在派生类中进行强制转换
【发布时间】:2011-12-26 02:51:25
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# refactoring


    【解决方案1】:

    您可以将基类设为泛型:

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

    【讨论】:

    • 抽象类应该有protected构造函数。
    • 这如何帮助处理传递给 AService 的 TModel 可能有 NewInt 的事实?
    • 非常好的解决方案,我喜欢这个 :) 非常感谢!
    【解决方案2】:

    您可以在派生类中维护您的模型引用:

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

    【讨论】:

    • 是的,但我认为他没有首先引入新领域是有原因的(即 MyModelA 仍然必须扮演 MaModel 的角色)
    • 看起来这是我的解决方案的一个更干净的版本,没有使用演员,但它仍然是相同的想法。
    • 是的,你问过如何避免强制转换:)
    【解决方案3】:

    使用 _tmp 的解决方案让您不必一直编写手动转换,但奇怪的对象设计问题仍然存在。

    我猜你的 NewInt 是用来执行 MyModel 中也存在的某种功能(否则你最好先创建一个新类)。我想知道您是否不能以 MyModelA 不必公开任何新内容的方式封装该功能。这可能意味着要更改 AB 的定义,以便进行此类概括。

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

    【讨论】:

    • 好吧,SLaks 的回答很好地提供了一个与域无关的答案,所以我的最后一个答案可能是错误的。不过,可能值得研究一下为什么必须在 MyModelA 中公开一个新的公共属性
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    相关资源
    最近更新 更多