【问题标题】:How do i extend a property through inheritance?如何通过继承扩展属性?
【发布时间】:2011-03-08 08:49:08
【问题描述】:

我有一个包含价格曲线字典的类 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>>();
    }
}

我不确定这是否适合这种情况。我还想将枚举类型限制为十进制。有什么想法吗?

更新:我忘了提到我需要将所有产品保存在一个通用列表(列表)中

【问题讨论】:

  • 您不需要在派生类中创建第二个字典字段,请解释一下为什么需要“将枚举类型限制为十进制”?
  • 我在金融业工作,因此是十进制

标签: c# inheritance enums properties constraints


【解决方案1】:

这是隐藏成员。

多态是指改变某些子类中的方法、属性实现,比如“派生”或“继承”类。但是,无论如何,它的签名是不可变的。

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>>();

如果我没记错的话,这就是你的方法;)

编辑:对不起,我忘了更改您的基类中的某些内容,请再次检查此答案:)

【讨论】:

  • Product 构造函数中的赋值无法编译:无法将源类型“System.Collections.Generic.Dictionary”转换为目标类型“TPrice”。我忘了提,我还想将这些产品保存在另一个通用列表中
  • 嗯,事实上,这是一个“错字”,让构造函数留下这个赋值。我刚刚编辑删除它。为什么?既然 TPrice 是一个泛型类型,为什么要用字典来设置“PriceList”呢?您必须在创建“Product”实例时执行此操作,因为如果“TPriceValue”是小数并且您想设置字典会发生什么? :)
  • 我已经猜到了。然后我如何将这样的对象传递给方法。如何将 Product 和 Product> 添加到 IList>???
  • 你需要逆变来这样做,但你不能在类中这样做(它仅限于委托和接口),遗憾的是,IList 接口不是逆变的!因此,您的选择是创建一个实现 IList 的 ICovariancableList 。而且您需要一个没有价格值和通用参数的基类,因此 T 将是 Product 的派生类。
【解决方案2】:

我会尽量简化,因为这段代码有一股难闻的味道。

你为什么不在Product 内部的SpecialProduct 中使用PriceList,并让子字典始终只有一个值PriceType.Default 或类似的值?然后,您将能够使用所有 Products 而无需任何强制转换或检查。

【讨论】:

    【解决方案3】:

    这种方法怎么样?

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

    也许这更符合您的要求。

    问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-27
      • 1970-01-01
      • 1970-01-01
      • 2010-11-07
      • 2017-11-23
      • 2011-03-31
      • 1970-01-01
      相关资源
      最近更新 更多