Как продлить собственность через наследование? - PullRequest
1 голос
/ 08 марта 2011

У меня есть класс Product, который содержит словарь с кривой цен. Ключ - это строка, которую можно проанализировать в метке времени.

public class Product
{
    public virtual int Id { get; set; }
    public virtual IDictionary<string, decimal> PriceList { get; set; }

    public Product()
    {
        this.PriceList = new Dictionary<string, decimal>();
    }
}

Теперь мне нужен второй класс с большим количеством цен для каждого ключа

public class SpecialProduct : Product
{
    public enum PriceType
    {
        BusineesDays,
        Weekends,
        Holidays
    }

    public virtual IDictionary<string, IDictionary<PriceType, decimal>> PriceList { get; set; }

    public SpecialProduct()
    {
        this.PriceList = new Dictionary<string, IDictionary<PriceType, decimal>>();
    }
}

Я не уверен, что это хороший подход для этого случая. Я также хотел бы ограничить тип enum десятичным. Есть идеи?

ОБНОВЛЕНИЕ: я забыл упомянуть, что мне нужно сохранить все продукты в общем списке (списке)

Ответы [ 3 ]

1 голос
/ 08 марта 2011

Это скрытие члена.

Полиморфизм означает изменение метода, реализацию свойства в некотором подклассе, скажем, «производный» или «унаследованный» класс. Но, во всяком случае, его подпись неизменна.

C # предоставляет хороший способ скрыть участников: ключевое слово "new".

Вам просто нужно поставить "new" перед модификатором доступа в производном классе, и вы его получили. Если вы этого не сделаете, компилятор C # предложит вам сделать это.

Кстати, если ваша цель - использовать полиморфизм, вы должны учитывать дженерики.

Ваш базовый класс должен иметь универсальный параметр "TPriceValue", и он будет выглядеть следующим образом:

public class Product<TPriceValue>
{
    public virtual int Id { get; set; }
    public virtual TPriceValue PriceList { get; set; }

    public Product()
    {
        // NOTE/EDIT: You wouldn't initialize "PriceList" here...
    }
}

Итак, если вы хотите, чтобы значение вашей цены было десятичным, вам следует создать экземпляр класса следующим образом:

new Product<decimal>();

Или, если вы хотите, чтобы ваше значение в качестве другого словаря:

new Product<IDictionary<PriceType, decimal>>();

Если я не ошибаюсь, это путь в вашем случае;)

РЕДАКТИРОВАТЬ: Извините, я забыл что-то изменить в вашем базовом классе, проверьте еще раз этот ответ:)

0 голосов
/ 08 марта 2011

А как насчет этого подхода?


public abstract class AProductBase<T>
{
  public IDictionary<string, T> PriceList { get; set; }
  ...
}

public class Product : AProductBase<decimal>
{
  ...
}

public enum PriceTypeEnum { ... }

public class SpecialProduct : AProductBase<IDictionary<PriceTypeEnum, decimal>>
{
  ...
}

Возможно, это лучше соответствует вашим требованиям.

Привет

0 голосов
/ 08 марта 2011

Я бы пошел на упрощение, так как этот код имеет определенный неприятный запах.

Почему бы вам не использовать PriceList in SpecialProduct внутри Product, и сделать так, чтобы под-словарь всегда имел только одно значение PriceType.Default или что-то подобное? После этого вы сможете использовать все Products, не требуя приведения или проверки.

...