Я создал несколько интерфейсов для описания коллекции и ее элементов: IetCollection и IetCollectionItem.И, конечно, у меня есть два класса, реализующих эти два интерфейса: TetCollection и TetCollectionItem (оба наследуются от TInterfacedObject.)
Затем у меня есть серия интерфейсов, где интерфейсы верхнего уровня наследуются от IetCollectionItem, а остальные от него (позволяютназовите их ISomeBasicType и ISomeSpecificType1 и ISomeSpecificType2.)
Класс TSomeBasicType наследуется от класса TetCollectionItem и также реализует ISomeBasicType.Другие классы в иерархии наследуются от TSomeBasicType и реализуют их соответствующие интерфейсы (т.е. ISomeSpecificType1 и ISomeSpecificType2.)
Когда я заполняю коллекцию, я использую фабричный метод, чтобы получить ссылку на ISomeBasicType.До этого момента все работало просто отлично.
Но когда я пытаюсь обойти коллекцию и спросить, поддерживает ли элемент коллекции либо ISomeSpecificType1, либо ISomeSpecificType2, я получаю ответ «нет».
Я былпытаясь решить эту проблему, и я ничего не добился, поэтому любая помощь будет принята с благодарностью.
Вот некоторый код:
// This is the basic type
IetCollectionItem = interface
end;
// Implementation of the basic type
TetCollectionItem = class(TInterfacedObject, IetCollectionItem)
end;
ISomeBasicType = interface(IetCollectionItem)
end;
ISomeSpecificType1 = interface(ISomeBasicType)
end;
// Implements ISomeBasicType, should inherit implementation of IetCollectionItem
// from TetCollectionItem
TSomeBasicType = class(TetCollectionItem, ISomeBasicType)
end;
// Implements ISomeSpecificType1, should inherit implementation of ISomeBasicType
// from TSomeBasicType and implementation of IetCollectionItem from
// TetCollectionItem
TSomeSpecificType1 = class(TSomeBasicType, ISomeSpecificType1)
end;
Это код, который я использую для заполнения коллекции:
var
aBaseType: ISomeBasicType;
aSpecificType: ISomeSpecificType1;
begin
aBaseType:= TheFactory(anID, aType); // Returns a reference to ISomeBasicType
if Supports(aBaseType, ISomeSpecificType1, aSpecificType) then
begin
// Do something to the specific type
aTypeCollection.Add(aSpecificType);
end
else
aTypeCollection.Add(aBaseType);
А вот код, который не работает: я перебираю коллекцию и проверяю, поддерживает ли какой-либо из ее элементов один из дочерних интерфейсов.
var
iCount: Integer;
aBaseType: ISomeBasicType;
aSpecificType: ISomeSpecificType1;
begin
for iCount:= 0 to Pred(aTypeCollection.Count) do
begin
aBaseType:= aTypeCollection[iCount];
// This is where Supports fails
if Supports(aBaseType, ISomeSpecificType1, aSpecificType) then
begin
end;
end;
end;
А вот код для TheFactory:
function TheFactory(const anID: Integer; const aType: TetTypes): ISomeBasicType;
begin
Result:= nil;
case aType of
ptType1 : Result:= TSomeSpecificType1.Create(anID, aType);
ptType2 : Result:= TSomeSpecificType2.Create(anID, aType);
end;
Assert(Assigned(Result), rcUnknonwPhenomenonType);
end; {TheFactory}