代码之家  ›  专栏  ›  技术社区  ›  Birger

检查对象是否从泛型类继承

  •  3
  • Birger  · 技术社区  · 15 年前

    我有一个泛型列表类:

    TMyObjectlist<T: TMyObject> = class(TObjectList<T>);
    

    TMyDerivedObjectList = class(TMyObjectList<TMyDerivedObject>);
    

    我想检查tmydrivedobjectlist的实例MyList是否从TMyObjectList继承,但是:

    MyList.InheritsFrom(TMyObjectlist<TMyObject>)
    

    返回False。

    原来MyList.Classparent是 TMyObjectList<TMyDerivedObject> .

    4 回复  |  直到 15 年前
        1
  •  6
  •   Cosmin Prund    15 年前

    只要为这两个列表对象绘制继承方案,您就会清楚地看到为什么InheritsFrom不起作用。在泛型中。我们有:

    TEnumerable<T> = class abstract;
    TList<T> = class(TEnumerable<T>);
    TObjectList<T> = class(TList<T>);
    

    在你的例子中,我们有:

    TMyObject = class;
    TMyDerivedObject = class(TMyObject);
    

    我们得到了这两棵遗传树:

    TObject
    |
    TEnumerable<TMyDerivedObject>
    |
    TList<TMyDerivedObject>
    |
    TObjectList<TMyDerivedObject>
    

    然后我们有:

    TObject
    |
    TEnumerable<TMyObject>
    |
    TList<TMyObject>
    |
    TObjectList<TMyObject>
    

    如您所见,两种列表类型的唯一共同祖先是TObject!

        2
  •  1
  •   Mason Wheeler    15 年前

    这是因为您的列表不是从泛型类型从基类继承的类似列表继承的。它们不能像泛型类型那样互相替代。事实上,如果不破坏语言中很多东西所依赖的类型安全性,它们就不可能。

    为了理解原因,想象一下将MyList传递给一个期望 TMyObjectlist<TMyObject>

    有很多方法可以解决这个问题,但是它们还没有在Delphi中实现。希望Delphi团队能尽快着手解决这个问题,因为这将使泛型变得更加有用。

        3
  •  1
  •   nang    15 年前

    在Delphi中,构造的类型与其类型参数不协变。 鉴于 T, U, V U <= V ,那么 T<U> is not <= T<V>

    看到了吗 Covariance and contravariance .

        4
  •  0
  •   Robert Love    15 年前

    TObjectList<t> 在指定类型exists时创建的实例的编译代码中不存在。

    所以不能检查它是否派生自非具体类。