分配包含更多派生类的列表时,将实体关系设计应用于抽象类时出错



我正在定义两个抽象类:AC1AC2AC1有一个属性(变量(,它是类型AC2(List<AC2>(的List(这是我定义一对多关系的方式(。

然后,我定义了来自AC1(R1 : AC1(和R2 : AC2R1。当我编写 R1 的构造函数时,问题就来了。我将 R2 (List<R2>( 类型的列表作为参数传递,然后尝试将其分配给 AC1 (List<AC2>( 中定义的属性(变量(,但这失败了,因为它无法隐式从 R2 转换为 AC2(即使 R2 来自 AC2(。

代码示例:

abstract class AC2
{
//several properties and methods here
}
abstract class AC1
{
List<AC2> dammVariable {get; set;} //problematic variable (see class R1)
//other stuff here
}
class R2 : AC2
{
//some properties exclusive for R2 here
public R2(){}
}
class R1 : AC1
{
//some properties exclusive for R1 here
public R1(List<R2> r2s)
{
this.dammVariable = r2s; //I found the error right here
}
}

我将有一些来自此抽象类的其他类,但是每次我创建一个来自AC2的类(例如X2(时,我都需要一个具有List<X2>的X1类。

我在设计或实施方面是否失败?

我将不胜感激任何帮助。

这里有几个问题。

  • 首先,您需要将dammVariable的保护级别更改为至少protected,以便在子类中访问它。

  • 但是,您将面临一个类型安全问题:

CS0029:无法将类型System.Collections.Generic.List<R2>隐式转换为System.Collections.Generic.List<AC2>

这是因为List<T>是不变的,因此尽管R2AC2之间存在继承关系,您将无法将List<R2>分配给List<AC2>

假设一旦分配,您实际上永远不需要从dammVariable中添加/删除元素,将类型从 List 更改为允许协方差的类型,例如

abstract class AC1
{
protected IEnumerable<AC2> dammVariable {get; set;}
)

更多关于本问题中的协方差/逆变

首先,我假设dammVariable是受保护的或公共的,因为如果没有,它将失败。

其次,C# 无法从 List隐式转换为 List。你应该使用 for 循环分配 dammVariable 的每个元素。

class R1 : AC1
{
public R1(List<R2> r2s)
{
this.dammVariable = r2s;
this.dammVariable= new List<AC2>();
for(int i = 0; i<r2s.Count; i++)
{
this.dammVariable[i] = r2s[i];
}
}
}

最新更新