【问题标题】:Check if object inherits from generic class检查对象是否继承自泛型类
【发布时间】:2011-03-06 20:16:19
【问题描述】:

我有一个通用列表类:

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

和一个派生列表类:

TMyDerivedObjectList = class(TMyObjectList<TMyDerivedObject>);

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

MyList.InheritsFrom(TMyObjectlist<TMyObject>)

返回 False。

原来 MyList.Classparent 的类型是TMyObjectList&lt;TMyDerivedObject&gt;

有人知道在这种情况下如何检查 InheritsFrom 吗?

【问题讨论】:

    标签: delphi generics inheritance


    【解决方案1】:

    在 Delphi 中,构造类型与其类型参数不协变。 给定T, U, VU &lt;= V,然后是T&lt;U&gt; is not &lt;= T&lt;V&gt;

    Covariance and contravariance

    【讨论】:

      【解决方案2】:

      只需为两个列表对象制定继承方案,您就会清楚地看到为什么 InheritsFrom 不起作用。在 Generics.Collections 我们有:

      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!

      【讨论】:

        【解决方案3】:

        TObjectList&lt;t&gt; 在您指定类型存在时创建的实例上的编译代码中不存在。

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

        【讨论】:

        • TobjectList.InheritsFrom(TList) 返回 True,因此您可以检查类是否派生自通用(非具体)类。
        • TList 是具体的。 TList 不是。
        【解决方案4】:

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

        要理解为什么,想象一下将 MyList 传递给一个需要 TMyObjectlist&lt;TMyObject&gt; 的例程。一切都很好,直到例程调用 .Add 并将一个 TMyIncompatibleObject(也是 TMyObject 的后代)粘贴到列表中。那你就破坏了类型安全。

        有一些方法可以解决这个问题,但它们还没有在 Delphi 中实现。希望 Delphi 团队能尽快解决这个问题,因为这会使泛型更加有用。

        【讨论】:

          猜你喜欢
          • 2019-06-25
          • 2012-01-10
          • 2023-03-22
          • 2012-10-09
          • 1970-01-01
          • 2016-10-14
          • 2016-10-05
          • 2023-04-03
          • 1970-01-01
          相关资源
          最近更新 更多