无法弄清楚基础/派生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;
}
有更优雅的方式吗?
答案 0 :(得分:3)
没有,这种方法有潜在危险。您可能需要重新评估您要执行的操作。
B2.list
是B1
个对象的集合。它的接口契约声明它包含B1
。在派生类中,D2.list
是D1
个对象的集合。由于D1
是B1
的子类,因此这是一个更严格的要求。基类的列表完全可能包含B1
但不是D1
的对象。在这种情况下,您的代码将因无效的强制转换异常而失败。
所以这种语言不是为了让你这么做而设计的,因为它不安全; 你试图缩小(而不是扩展)基类的行为。这通常是code smell。您必须明确地执行此操作,并且仅,如果您知道这对您的特定问题既安全又好的设计。
此外,作为观察,请注意您是"hiding" the base class's properties。编译器可能会给你一个警告。如果需要真正的覆盖,则需要创建基本属性virtual
并在派生类中使用override
关键字。或者,使用new
关键字确认隐藏是您想要的,并消除警告,但请确保您理解这意味着什么(如果通过基数的引用访问属性,您将不会获得多态行为类型)。