Сложная наследовательная ситуация. Возвращаемый базовый объект из производного класса

У меня довольно сложная ситуация с наследованием. У меня есть базовый класс DataObject который наследует мой класс Invoice. Я хочу, чтобы сохранить Invoice - DataObject Invoice Invoice объекта с помощью DataObject метод сохранения, а затем вернуть 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 который был сохранен в базе данных. Я даже не уверен, что это возможно, но я действительно надеюсь, что это так.

1 ответ

Работая с вашими ограничениями, кажется, что самый простой способ сделать это - объявить "Сохранить как абстрактный" (так же как InvoiceObject) и позволить конкретным templatized подклассам переопределить его, например:

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;
 }
}
</invoice></t></t></t>

EDIT: в ответ на ваш комментарий реализация по умолчанию "Сохранить" означает, что любой объект Save return должен быть DataObject, поскольку реализация Save по умолчанию является return this; внутри объекта DataObject (надеюсь, что это имеет смысл).

Вы можете сделать это, используя шаблон Curiously Recurring Template, но для этого требуется, чтобы вы возвращали DataObject из вашего сохранения, например:

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

}
</invoice></t></t></t></t></t></t>

licensed under cc by-sa 3.0 with attribution.