2013-08-23 3 views
0

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

+0

Я не уверен, если это то, что вы хотите, вы должны реализуйте Save() в InvoiceObject и вызовите base.Save() оттуда. и не возвращать base.Save() из счета-фактуры, вместо этого возвратите это из счета-фактуры? – Siva

+1

Можете ли вы использовать интерфейс вместо наследования классов? – Dan

+0

Я бы предпочел использовать наследование, так как это позволит мне реализовать «Сохранить один раз» и изменить его по мере необходимости дальше по дереву наследования. – coryrwest

ответ

3

Работа в ваших ограничений, кажется, самый простой способ сделать это, чтобы объявить Сохранить как абстрактное (а также 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; 
    } 
} 

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

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

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

+1, но вы можете предоставить DataObject ограничение с помощью T: DataObject, и вы можете удалить InvoiceObject –

+0

. Это довольно просто , но я стараюсь избегать реализации 'Save' для каждого объекта, так как большинство из них будет использовать метод« по умолчанию »Save, и очень немногие должны быть реализованы иначе, чем база. – coryrwest

+0

Вы можете создать атрибут и использовать отражение в базовом классе для перечисления всех свойств, которые вы хотите использовать для сериализации. –

Смежные вопросы