我正在定义两个抽象类:AC1
和AC2
。AC1
有一个属性(变量(,它是类型AC2
(List<AC2>
(的List
(这是我定义一对多关系的方式(。
然后,我定义了来自AC1
(R1 : AC1
(和R2 : AC2
的R1
。当我编写 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>
是不变的,因此尽管R2
和AC2
之间存在继承关系,您将无法将List<R2>
分配给List<AC2>
。
假设一旦分配,您实际上永远不需要从dammVariable
中添加/删除元素,将类型从 List 更改为允许协方差的类型,例如
abstract class AC1
{
protected IEnumerable<AC2> dammVariable {get; set;}
)
更多关于本问题中的协方差/逆变
首先,我假设dammVariable是受保护的或公共的,因为如果没有,它将失败。
其次,C# 无法从 List
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];
}
}
}