假设我有这两个类
class BaseClass
{
protected HashSet<BaseClass> container;
}
class DerivedClass : BaseClass
{
DerivedClass()
{
container = new HashSet<DerivedClass>();
}
}
然后我收到一个错误:无法转换。
由于每个 DerivedClass(应该)是一个 BaseClass,我不太清楚为什么会抛出这个错误,但确实如此。
目标是让 BaseClass 对 container
执行各种操作,只有特别具体的行为与 DerivedClass 相关 - 其中,要求容器的类型为 HashSet<DerivedClass>
.
这个目标通常是如何实现的?
最佳答案
每个DevrivedClass
是 BaseClass
,但反之则不然。 HashSet<T>
不能协变,因为它允许写操作 ( Add
)。所以在你的场景中这是可能的:
class BaseClass
{
protected HashSet<BaseClass> container;
public DoSomething()
{
container.Add(new BaseClass()); // not legal if container is really a List<DerivedClass>
}
}
您可以将容器的类型更改为协变的:
class BaseClass
{
protected IEnumerable<BaseClass> container;
}
class DerivedClass : BaseClass
{
DerivedClass()
{
container = new HashSet<DerivedClass>();
}
}
但是只有派生类可以将项目添加到 container
(这可能适用于您的设计)。
您也可以尝试使基类泛化:
class BaseClass<T> where T:BaseClass<T>
{
protected HashSet<T> container;
}
class DerivedClass : BaseClass<DerivedClass>
{
DerivedClass()
{
container = new HashSet<DerivedClass>();
}
}
这看起来有点奇怪,但是一个类包含相同类型的对象列表又看起来很奇怪,所以也许在您的真实场景中它是有意义的。
关于c# - 模板参数中的 "Covariance",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18193498/