2010-06-22 53 views
3

對象繼承我有一個泛型列表類:檢查是否從通用類

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

和派生列表類:

TMyDerivedObjectList = class(TMyObjectList<TMyDerivedObject>); 

我想檢查是否TMyDerivedObjectList的實例MYLIST從TMyObjectList繼承但是:

MyList.InheritsFrom(TMyObjectlist<TMyObject>) 

返回False。

事實證明,MyList.Classparent的類型是TMyObjectList<TMyDerivedObject>

有沒有人知道如何在這種情況下檢查InheritsFrom?

回答

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> 

正如你所看到的,onl這兩種列表類型的共同祖先是TObject!

0

TObjectList<t>在您指定類型存在時創建的實例的編譯代碼中不存在。

所以你不能檢查它是否從非具體類派生。

+1

TobjectList .InheritsFrom(TList )返回True,因此您可以檢查類是否從泛型(非具體)類派生。 – 2010-06-22 15:34:37

+1

TList 是具體的。 TList 不是。 – 2010-06-22 18:26:02

1

這是因爲您的列表沒有從通用類型繼承自基類的類似列表繼承。它們不能像泛型類型那樣替代對方。事實上,他們不可能是這樣的,除非破壞語言中許多事物所依賴的類型安全。

要理解爲什麼,想象一下將MyList傳遞給期望TMyObjectlist<TMyObject>的例程。一切都很好,直到例程調用。添加並粘貼TMyIncompatibleObject,它也從TMyObject下降到列表中。然後你打破了類型安全。

有解決這個問題的方法,但它們還沒有在Delphi中實現過。希望德爾菲團隊能夠儘快解決它,因爲這會使泛型非常有用。

1

在Delphi中,構造類型與它們的類型參數不是協變的。 給定T, U, VU <= V,然後T<U> is not <= T<V>

請參閱Covariance and contravariance