This has been asked several different ways already - but I haven't found my answer yet.
Can someone clarify a few things for me please. Using : Delphi XE2
I have quite a big BaseObject that I use for almost everything. Along with it I have a Generic list - BaseList.
Delarations go like this :
TBaseObject = class
... a lot of properties and methods ...
end;
TBaseList<T: TBaseObject> = class(TObjectList<T>)
... some properties and methods ...
end;
I have recently tried to change the TBaseList declaration from a very old TStringList using Objects[] property... to this never more versatile Generics list TObjectList.
But I run into some problems. The BaseUnit is one file ... and every time I descend my BaseObject I also make a specialized list to follow it.
So I would go and do something like :
TCustomer = class(TBaseObject)
... customer related stuff ...
end;
TCustomerList<T: TCustomer> = class(TBaseList<T>)
... customer list specific stuff ...
end;
But now I would like an object to contain a list - that can hold any object. And I thought I could do it like this
TControlObject = class(TBaseobject)
FGenList: TBaseList<TBaseObject>;
end;
Since BaseList and BaseObject is top of my hierarchy I assumed that such a List would be able to hold any list I could think of.
But I have a feeling that it is here I fail ...
a TBaseList<TBaseobject>
is somehow not comparable to TCustomerList<TCustomer>
...
Even if TCustomerList
and TCustomer
is descended from my base.
I was hoping to be able to use generics in the baselist for instaciating new objects.
ie. using T.Create
in a populate method.
Here is example of complete hierarchy:
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;
Given the above hierarchy - why can't I :
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;
Calling a procedure that handles the base class for all lists fails the same way ...
Procedure LogStuff(SomeList : TBaseList<TBaseObject>)
begin
writeln(Format( 'No. Elements in list : %d',[SomeList.Count]));
end;
Can someone punch me and tell me what I'm doing wrong here?
TPersonList = class(TObject)
which holds aFList: TBaseList<TBaseObject>
member that you instantiate asFList := TBaseList<TPerson>.Create
– DituriFList := TBaseList<TPerson>.Create
is not possible - since FList is of another Type -TBaseList<TBaseObject>
. – GironTInterfacedList<T> = class(TInterfacedObject, IList<T>)
with a privateFList: TList<T>;
member and a protectedfunction Add(const Value: T): Integer;
The Add function checks that the object instance passed in is actually an object of the required type. See #6389857 for the code (the question was more oriented towards creating an interfaced list and supporting enumerators) – Dituri