2014-02-05 26 views
2

不能完全弄清楚基地/派生List<type>的动态。主项目“派生”引用“基础”项目。基地项目工作正常,MOD需要保持在最低限度。派生项目仅添加与服务的交互,但不会修改基本功能本身。基类名单<type>财产往/从派生类名单<derivedType>财产

基类:

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; 
     } 

是否有更优雅的方式?

回答

3

没有,这种方法是潜在的危险。您可能需要重新评估您要做的事情。

​​是B1对象的集合。它的接口合同规定它包含B1's。在你的派生类中,D2.listD1对象的集合。由于D1B1的一个子类,这是一个更严格的要求。基类的列表完全可能包含一个B1而不是D1的对象。在这种情况下,您的代码将失败并显示无效的转换异常。

所以语言的目的不是让你这样做,因为它不安全; 您试图缩小(而不是扩展)基类的行为。这通常是code smell。你必须明确地做到这一点,并且只有如果你知道这是既安全又适合你的具体问题的设计。

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

+0

非常有帮助......谢谢。是的,这是一种特殊情况,其中由于派生的静态方法,基本属性必须可以派生为派生属性。因此,派生的属性现在有独特的名称,一切都很好。再次,谢谢。 –