Home How to use TObjectList for arbitrary class type?

# How to use TObjectList for arbitrary class type?

Jerry Dodge
1#
Jerry Dodge Published in 2018-01-11 15:31:34Z
 I'm still a bit fuzzy with generics in Delphi, but have been using TObjectList<> quite widely. Now I have a situation where I have a base class with such a private field, but needs to be created for an arbitrary class, also inherited from another base. To clarify, I have two base classes: type TItem = class; TItems = class; TItemClass = class of TItem; TItem = class(TPersistent) private FSomeStuffForAllIneritedClasses: TSomeStuff; end; TItems = class(TPersistent) private FItems: TObjectList; FItemClass: TItemClass; public constructor Create(AItemClass: TItemClass); destructor Destroy; override; function Add: TItem; ... end;  This pair of classes is then further inherited into more specific classes. I'd like the object list to be shared for all of them, while each holds actually a different type internally. type TSomeItem = class(TItem) private FSomeOtherStuff: TSomeOtherStuff; ... end; TSomeItems = class(TItems) public function Add: TSomeItem; //Calls inherited, similar to a TCollection procedure DoSomethingOnlyThisClassShouldDo; ... end;  Now the problem is when it comes to creating the actual object list. I'm trying to do it like this: constructor TItems.Create(AItemClass: TItemClass); begin inherited Create; FItemClass:= AItemClass; FItems:= TObjectList.Create(True); end;  However, the code insight complains about this: Undeclared Identifier AItemClass Even more, the compiler has yet a different complaint: Undeclared Identifier TObjectList Where, I do in fact have System.Generics.Collections used in this unit. What am I doing wrong here, and how should I do this instead?
Stefan Glienke
2#
Stefan Glienke Reply to 2018-01-11 15:45:46Z
 Make TItems generic: TItems = class(TPersistent) private FItems: TObjectList; public constructor Create; destructor Destroy; override; function Add: T; ... end; constructor TItems.Create; begin inherited Create; FItems:= TObjectList.Create(True); end; function TItems.Add: T; begin Result := T.Create; FItems.Add(Result); end;  If you inherit, simply put the correct generic parameter: TSomeItems = class(TItems) public procedure DoSomethingOnlyThisClassShouldDo; ... end; 
Jerry Dodge
3#
Jerry Dodge Reply to 2018-01-11 15:31:34Z
 The TObjectList is not meant to be used in that manner. The fact that it was originally defined as TObjectList means that it will expect you to create it this way as well. It needs to be defined with the precise class you intend to create it as. Instead, just create it with TItem, and then whenever you create a new item which is supposed to be added to this list, then you create it using the class type. Any time you need to access the items in this list, just cast them on the fly. For example... Result:= FItemClass.Create; FItems.Add(Result);  ...can be the contents of your Add function.
 You need to login account before you can post.
Processed in 0.361019 second(s) , Gzip On .