DELPHI: Обобщения и полиморфизм

Об этом уже спрашивали несколькими разными способами, но я еще не нашел своего ответа.

Кто-нибудь может мне кое-что прояснить. Использование: Delphi XE2

У меня довольно большой BaseObject, который я использую почти для всего. Наряду с этим у меня есть общий список - BaseList.

Изменения выглядят следующим образом:

TBaseObject = class
... a lot of properties and methods ...
end;

TBaseList<T: TBaseObject> = class(TObjectList<T>)
... some properties and methods ... 
end;

Я недавно попытался изменить объявление TBaseList с очень старого TStringList, используя свойство Objects [] ... на этот никогда не более универсальный список универсальных шаблонов TObjectList.

Но я столкнулся с некоторыми проблемами. BaseUnit - это один файл ... и каждый раз, когда я спускаюсь по моему BaseObject, я также составляю специальный список, чтобы следовать ему.

Итак, я бы сделал что-то вроде:

TCustomer = class(TBaseObject)
... customer related stuff ...
end;

TCustomerList<T: TCustomer> = class(TBaseList<T>)
... customer list specific stuff ...
end;

Но теперь я хотел бы, чтобы объект содержал список - который может содержать любой объект. И я подумал, что смогу сделать это вот так

TControlObject = class(TBaseobject)
  FGenList: TBaseList<TBaseObject>; 
end;

. Поскольку BaseList и BaseObject находятся на вершине моей иерархии, я предположил, что такой List сможет содержать любой список, который я мог придумать.

Но у меня такое ощущение, что именно здесь я проигрываю ... a TBaseList почему-то несопоставим с TCustomerList ... Даже если TCustomerList и TCustomer являются потомками моей базы.

Я надеялся, что смогу использовать дженерики в базовом списке для создания новых объектов. т.е. используя T.Create в методе заполнения.

Вот пример полной иерархии:

Base Unit;
TBaseObject = class
end;
TBaseList<T:TBaseObject> = class(TObjectList<T>)
end;

CustomCustomer Unit;
TCustomCustomer = class(TBaseObject) 
end;
TCustomCustomerList<T:TCustomCustomer> = class(TBaseList<T>)
end;

Customer Unit;
TCustomer = class(TCustomCustomer)
end;
TCustomerList<T:TCustomer> = class(TCustomCustomerList<T>)
end;

CustomPerson Unit;
TCustomPerson = class(TBaseObject) 
end;
TCustomPersonList<T:TCustomPerson> = class(TBaseList<T>)
end;

Person Unit;
TPerson = class(TCustomPerson)
end;
TPersonList<T:TPerson> = class(TCustomPersonList<T>)
end;

Учитывая приведенную выше иерархию - почему я не могу:

var    
  aList : TBaseList<TBaseObject>;  // used as a list parameter for methods
  aPersonList : TPersonList<TPerson>;
  aCustomerList : TCustomerList<TCustomer>;
begin
  aPersonList := TPersonList<TPerson>.Create;
  aCustomerList := TCustomerList<TCustomer>.Create;

  aList := aCustomerList;  <-- this FAILS !!  types not equal ..

end;

Вызов процедуры, которая обрабатывает базовый класс для всех списков, терпит неудачу одинаково ...

Procedure LogStuff(SomeList : TBaseList<TBaseObject>)
begin
  writeln(Format( 'No. Elements in list : %d',[SomeList.Count]));
end;

Может ли кто-нибудь удари меня и скажи, что я здесь делаю не так?

10
задан Warren P 4 February 2012 в 15:40
поделиться