Проверьте, наследуется ли объект от универсального класса - PullRequest
3 голосов
/ 22 июня 2010

У меня есть универсальный класс списка:

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

и класс производного списка:

TMyDerivedObjectList = class(TMyObjectList<TMyDerivedObject>);

Я хочу проверить, наследует ли экземпляр MyList TMyDerivedObjectList от TMyObjectList, однако:

MyList.InheritsFrom(TMyObjectlist<TMyObject>)

возвращает False.

Получается, что MyList.Classparent имеет тип TMyObjectList<TMyDerivedObject>.

Кто-нибудь знает, как проверить InheritsFrom в этом случае?

Ответы [ 4 ]

6 голосов
/ 22 июня 2010

Просто нарисуйте схему наследования для обоих объектов списка, и вы ясно увидите, почему 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 голос
/ 22 июня 2010

В Delphi сконструированные типы не ковариантны с параметрами их типов.Дано T, U, V и U <= V, затем T<U> is not <= T<V>.

См. Ковариация и контравариантность .

1 голос
/ 22 июня 2010

Это потому, что ваш список не наследуется от аналогичного списка, универсальный тип которого наследует от базового класса.Они не могут заменять друг друга так же, как универсальные типы.Фактически, они не могут быть такими, не нарушая безопасность типов, от которой зависит многое в языке.

Чтобы понять почему, представьте, что MyList передается в процедуру, которая ожидает TMyObjectlist<TMyObject>.Все хорошо, вплоть до того, как подпрограмма вызывает .Add и вставляет в список объект TMyIncompatibleObject, который также происходит от TMyObject.Тогда вы нарушили безопасность типов.

Есть способы обойти эту проблему, но они еще не были реализованы в Delphi.Надеюсь, команда Delphi скоро справится с этим, потому что это сделает Generics намного более полезным.

0 голосов
/ 22 июня 2010

TObjectList<t> не существует в скомпилированном коде в экземпляре, который был создан, когда вы указали, что тип существует.

Таким образом, вы не можете проверить, является ли он производным от неконкретного класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...