无法完全弄清基本/派生的List<type>的动态。主项目“派生”引用“基础”项目。基础项目工作正常,并且mods必须保持在最低水平。派生项目仅添加与服务的交互,而不会修改Base功能本身。

基类:

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


有没有更优雅的方式?

最佳答案

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

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

因此,该语言并不是为了让您做到这一点而设计的,因为它并不安全;您试图缩小(而不是扩展)基类的行为。这通常是code smell。仅当您知道这既安全又是针对特定问题的良好设计时,才必须明确地执行此操作。

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

关于c# - 基本类list <type>属性与派生类list <derivedType>属性之间的关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21583942/

10-17 02:49