【问题标题】:Complex inheritance situation. Returning base object from derived class [duplicate]复杂的继承情况。从派生类返回基对象[重复]
【发布时间】:2013-08-23 21:43:09
【问题描述】:

我有一个涉及继承的复杂情况。我有一个基础 DataObject 类,我的 Invoice 类继承自该类。我想使用DataObject save 方法保存Invoice 对象,然后返回刚刚保存的Invoice 对象。

public abstract class DataObject {
    public virtual DataObject Save() {
        // Save data
        return this;
    }
}

派生类

public class InvoiceObject : DataObject {
    // base data for the class goes here
}

public class Invoice : InvoiceObject {
    public override DataObject Save() {
          // Somehow return an Invoice object here
          return base.Save();
    }
}

如果可能,我想避免使用强制转换。任何见解都会有所帮助。为了争论,结构必须保持不变。我无法删除InvoiceObject 对象,Save 方法必须返回保存到数据库中的整个Invoice 对象。我什至不确定这是否可能,但我真的希望是的。

【问题讨论】:

  • 我不确定这是否是您想要的,您必须在 InvoiceObject 中实现 Save() 并从那里调用 base.Save()。并且不要从 Invoice 返回 base.Save(),而是从 Invoice 返回 this?
  • 你能用接口代替类继承吗?
  • 我更喜欢使用继承,因为这将允许我实现一次保存并根据需要在继承树的下方进行更改。
  • @Peter 差不多但不完全。我不想将Invoice 指定为DataObject。我只想指定 InvoiceInvoiceObject 并且从扩展名是 DataObject

标签: c# asp.net inheritance


【解决方案1】:

在您的约束范围内工作,似乎最简单的方法是将 Save 声明为抽象(以及 InvoiceObject),并让具体的模板化子类覆盖它,如下所示:

public abstract class DataObject<T> {
     public abstract T Save();
}

public abstract class InvoiceObject<T> : DataObject<T> {
    // base data for the class goes here    
}

public class Invoice : InvoiceObject<Invoice> {
    public override Invoice Save() {            
        return this;
    }
}

编辑:作为对您的评论的回应,具有默认的“保存”实现意味着保存返回的任何对象都必须是 DataObject&lt;T&gt;,因为保存的默认实现是 return this;DataObject&lt;T&gt; 内(希望有道理)。

您可以使用Curiously Recurring Template Pattern 执行此操作,但这样做需要您从保存中返回DataObject&lt;T&gt;,如下所示:

public abstract class DataObject<T> where T : DataObject<T>{
     public virtual DataObject<T> Save(){
        return this;
     }
}

public abstract class InvoiceObject<T> : DataObject<T> where T : DataObject<T> {
    // base data for the class goes here    
}

public class Invoice : InvoiceObject<Invoice> {

}

【讨论】:

  • +1,但是你可以给 DataObject 一个约束 where T : DataObject 并且你可以删除 InvoiceObject
  • 这很容易,但我试图避免必须为每个对象实现Save,因为它们中的大多数将使用“默认”保存方法,然后很少需要以不同的方式实现基地。
  • 您可以创建一个属性并在基类中使用反射来枚举您想要序列化的所有属性。
  • 不完全是我想要的,但@DavidN 已经尽可能接近了。我决定摆脱 InvoiceObject 并让 DataObject 通用。
  • 在我阅读编辑之前提交了最后一条评论。很好的解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 2012-12-10
  • 2014-12-23
  • 2021-05-14
相关资源
最近更新 更多