我正在寻找一种通过继承参数化继承泛型的方法 - 或者如果不可能,那么这是获得相同功能的最接近方式。
请考虑以下事项:
B类继承自A类
D类继承自C类
现在,我有一个班级:
abstract class A<T> where T : C
使用构造函数:
public A(T t)
现在,我希望扩展A类:
class B<D> : A<C>
创建构造函数:
public B(D t) : base(t){ /*stuff here*/}
但是,这会引发编译时错误,因为D不是C.所以我的两个问题是:
a)有干净的方法吗?在最糟糕的情况下,我认为我可以用C代替D而没有什么问题,但也许这就是为什么这不是一个安全的想法?
b)我是否应该在子类定义中明确说明我的泛型,或者是否有更简洁的方法我应该使用约束类型?
答案 0 :(得分:2)
向B类添加where约束
class B<D> : A<C> where D : C
回答你的问题:
a)通过这个答案中的修复,到目前为止你的方法相当干净,如果有点抽象(主要是由于名字)。
b)如果子类本身要以与C的子类相关的通用方式添加值,那么您应该只将D泛型类型参数添加到子类B中,这是D的实例;或者如果子类本身不完整,则应该扩展并且需要C的知识子类为D.在这种情况下,您应该将其标记为抽象。
<强>更新强>:
我想再补充一点。在上面的签名中,T
的{{1}}参数在使用A<T>
类型的A成员中将为C.这可能是一个问题,如以下示例所示:
T
此示例中的代码无法编译。您将收到以下编译错误:
public class C {}
public class F : C {}
public class E : C {}
public class A<T> where T : C
{
protected T cSubclass;
public void SetCSubclass(T cSubclass) { this.cSubclass = cSubclass; }
}
public class B<D> : A<C> where D : C
{
public D GetCSubclass()
{
return this.cSubclass;
}
}
但是,如果我们将B类更改为以下内容,则会解决编译错误:
error CS0266: Cannot implicitly convert type 'C' to 'D'. An explicit conversion exists (are you missing a cast?)
原因是D是C的特定子类,但在前一版本中,我们只将A约束为任何形式的C,包括它自身及其任何子类。因此,我们可能会调用public class B<D> : A<D> where D : C
{
public D GetCSubclass()
{
return this.cSubclass;
}
}
,这将是GetCSubclass期望返回的不同类型。在后一版本中,我们将D指定为要在强制new B<F>.SetCSubclass(new E());
中仅使用B<F>.SetCSubclass
的实例的类型参数。
这为使用此类模式的开发人员提供了更高程度的类型安全性。