使用继承的参数化继承泛型

时间:2015-07-24 18:00:56

标签: c# generics inheritance

我正在寻找一种通过继承参数化继承泛型的方法 - 或者如果不可能,那么这是获得相同功能的最接近方式。

请考虑以下事项:

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)我是否应该在子类定义中明确说明我的泛型,或者是否有更简洁的方法我应该使用约束类型?

1 个答案:

答案 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的实例的类型参数。

这为使用此类模式的开发人员提供了更高程度的类型安全性。