基类列表<type>属性到/派生类列表<derivedtype>属性</derivedtype> </type>

时间:2014-02-05 17:15:11

标签: c# inheritance

无法弄清楚基础/派生List<type>的动态。主要项目“衍生”引用“基础”项目。基础项目工作正常,mods需要保持在最低限度。派生项目仅添加与服务的交互,但不会修改基本功能本身。

基础课程:

B1
{
  private int _prop;
  int prop
  {
    get{return _prop;}
    set{_prop = value;}
  }
}

B2
{
  private List<B1> _list;
  List<B1> list
  {
    get{return _list;}
    set{_list = value;}
  }
}

派生类:

D1:B1
{
  int prop
  {
    get{return base.prop;}
    set{base.prop = value;}
  }
}

D2:B2
{
  List<D1> list
  {
    get{return base.list;}/Problem area ... each base.B1 needs to be cast to a D1.
    set{base.list = value;}//... each D1 needs to be cast back to a B1
  }
}

必须将base.list中的每个B1强制转换为D1,以便使用D1特定方法,这些方法又与外部服务进行交互。试过这个,但不确定这是一个更好的策略。 (存在重载的构造函数以支持此功能。)

        get
        {
            List<D1> listD1 = new List<D1>();
            foreach (B1 b in base.list)
            {
                listD1.Add(new D1(B1));
            }
            return _listD1;
        }
        set
        {
            List<B1> listB1 = new List<B1>();
            foreach (D1 d in list)
            {
                listB1.Add(new B1(d.prop));
            }
            base.list = listB1;
        }

有更优雅的方式吗?

1 个答案:

答案 0 :(得分:3)

没有,这种方法有潜在危险。您可能需要重新评估您要执行的操作。

B2.listB1个对象的集合。它的接口契约声明它包含B1。在派生类中,D2.listD1个对象的集合。由于D1B1的子类,因此这是一个更严格的要求。基类的列表完全可能包含B1但不是D1的对象。在这种情况下,您的代码将因无效的强制转换异常而失败。

所以这种语言不是为了让你这么做而设计的,因为它不安全; 你试图缩小(而不是扩展)基类的行为。这通常是code smell。您必须明确地执行此操作,并且,如果您知道这对您的特定问题既安全又好的设计。

此外,作为观察,请注意您是"hiding" the base class's properties。编译器可能会给你一个警告。如果需要真正的覆盖,则需要创建基本属性virtual并在派生类中使用override关键字。或者,使用new关键字确认隐藏是您想要的,并消除警告,但请确保您理解这意味着什么(如果通过基数的引用访问属性,您将不会获得多态行为类型)。