Lazarus

Programming => General => Topic started by: J-23 on October 25, 2020, 04:06:12 pm

Title: List of classes with a generic type
Post by: J-23 on October 25, 2020, 04:06:12 pm
Hello,
How do I create a list of generic classes?

I have a generic class, e.g .:
Code: Pascal  [Select][+][-]
  1. generic TBaseEditor<T: TObject; F: TBaseWizardForm> = class(TObject)

I have the following classes that are derived from the generic class
Code: Pascal  [Select][+][-]
  1. TWizardConnectionEditor = class(specialize TBaseEditorClass<TConnection, TWizardConnectionForm>)
  2. TWizardCarEditor = class(specialize TBaseEditorClass<TCar, TWizardCarForm>)
  3. TWizardPeopleEditor = class(specialize TBaseEditorClass<TPeople, TWizardPeopleForm>)
  4.  
Now how to create a list that will accept generic classes

Code: Pascal  [Select][+][-]
  1. type
  2.   TListEditor// What type to give
  3. procedure Example;
  4. var
  5.   ConnectionEditor: TWizardConnectionEditor;
  6.   CarEditor: TWizardCarEditor:
  7.   PeopleEditor: TWizardPeopleEditor;
  8.   ListEditor: TListEditor;
  9. begin
  10.   ConnectionEditor:=TWizardConnectionEditor.Create;
  11.   CarEditor:=TWizardCarEditor.Create;
  12.   PeopleEditor:=TWizardConnectionEditor.Create;
  13.   ListEditor := TListEditor.Create;
  14.   ListEditor.Add(ConnectionEditor);
  15.   ListEditor.Add(CarEditor);
  16.   ListEditor.Add(PeopleEditor);
  17. end
  18.  
Hope everything is understandable.
Title: Re: List of classes with a generic type
Post by: PascalDragon on October 26, 2020, 09:29:20 am
You need to use the common base type as element type of the list, which in your case is TObject. If you want more common functionality you need to introduce another common base type (like e.g. TFPGList<> inherits from the non-generic TFPSList).
Title: Re: List of classes with a generic type
Post by: J-23 on October 26, 2020, 03:08:37 pm
We don't really understand each other.

I mean more or less about this construction:
Code: Pascal  [Select][+][-]
  1. type
  2.   TListEditor = specialize TFPGList<TBaseEditorClass<TObject, TBaseWizardDialogEditorClass>>

I was thinking about it as well as you that it will pass but all I am left with is a list of pointers or implement an interface
Title: Re: List of classes with a generic type
Post by: Warfley on October 27, 2020, 12:04:06 am
So the problem here is that two different generic specializations are completely different types, example:
Code: Pascal  [Select][+][-]
  1. type
  2.   generic TTestRec<T> = record
  3.     value: T;
  4.   end;
  5.  
  6.   TCharRec = specialize TTestRec<Char>;
  7.   TIntRec = specialize TTestRec<Integer>;

TCharRec here is a record that contains only a single char, therefore sizeof(TCharRec) = 1. TIntRec is a record that contains a single integer, therefore sizeof(TIntRec) = 4.
A list can not work with these different types, because it needs to know which element requires how much space.

While you are working with classes and not records, the size might not be an issue, but I think this example is the best way to show my point, this is not inheritence, two different generic specializations are simply two completely different types
Title: Re: List of classes with a generic type
Post by: Blaazen on October 27, 2020, 01:57:30 am
You can do simply
Code: Pascal  [Select][+][-]
  1. TListEditor = class(specialize TFPGObjectList<TObject>)
and then
Code: Pascal  [Select][+][-]
  1.   ConnectionEditor:=TWizardConnectionEditor.Create;
  2.   CarEditor:=TWizardCarEditor.Create;
  3.   PeopleEditor:=TWizardPeopleEditor.Create;
  4.   ListEditor := TListEditor.Create(True);
  5.   ListEditor.Add(ConnectionEditor);
  6.   ListEditor.Add(CarEditor);
  7.   ListEditor.Add(PeopleEditor);
will work.
Title: Re: List of classes with a generic type
Post by: PascalDragon on October 27, 2020, 09:26:57 am
We don't really understand each other.

I mean more or less about this construction:
Code: Pascal  [Select][+][-]
  1. type
  2.   TListEditor = specialize TFPGList<TBaseEditorClass<TObject, TBaseWizardDialogEditorClass>>

I was thinking about it as well as you that it will pass but all I am left with is a list of pointers or implement an interface

I understood you very well, it's you who did not understand me. You need to use the following:

Code: Pascal  [Select][+][-]
  1. TListEditor = specialize TFPGList<TObject>

This is the only variant that is correct with the code you showed.

The only other possibility you can do is to introduce a non-generic base class for your TBaseEditorClass<,> and use that.

Thus you'll have:

Code: Pascal  [Select][+][-]
  1. type
  2.   TSomeBaseClass = class(TObject);
  3.   TBaseEditorClass<T: TObject; F: TBaseWizardForm> = class(TSomeBaseClass);
  4.   TListEditor = specialize TFPGObjectList<TSomeBaseClass>;
Title: Re: List of classes with a generic type
Post by: J-23 on October 27, 2020, 11:23:52 pm
OK, thanks guys for the info. I have already done
TinyPortal © 2005-2018