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

时间:2010-06-22 13:53:28

标签: delphi generics inheritance

我有一个通用列表类:

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

和派生列表类:

TMyDerivedObjectList = class(TMyObjectList<TMyDerivedObject>);

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

MyList.InheritsFrom(TMyObjectlist<TMyObject>)

返回False。

事实证明,MyList.Classparent的类型为TMyObjectList<TMyDerivedObject>

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

4 个答案:

答案 0 :(得分:6)

只需为两个列表对象绘制继承方案,您就会清楚地看到为什么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!

答案 1 :(得分:1)

这是因为您的列表不从类似的列表继承,其泛型类型继承自基类。它们不能以与泛型类型相同的方式相互替代。事实上,他们不可能,而不是破坏语言中许多东西依赖的类型安全。

要理解原因,想象一下将MyList传递给期望TMyObjectlist<TMyObject>的例程。一切都很好,直到例程调用。添加并粘贴TMyIncompatibleObject,它也从TMyObject下降到列表中。然后你破坏了类型安全。

有很多方法可以解决这个问题,但它们尚未在Delphi中实现。希望Delphi团队很快就能解决这个问题,因为这会让Generics变得更有用。

答案 2 :(得分:1)

在Delphi中,构造类型与其类型参数不协变。 给定T, U, VU <= V,然后T<U> is not <= T<V>

请参阅Covariance and contravariance

答案 3 :(得分:0)

在指定类型存在时创建的实例上的编译代码中不存在

TObjectList<t>

因此,您无法检查它是否来自非具体类。