Generics and constraints in Delphi is still a bit of pain.
A while ago, I needed a factory for threads. It was more convoluted than I meant it to be, so I had a short chat with Stefan Glienke.
He came up with an example similar to the one below. I tore it apart so you can on each line see what the compiler dislikes.
This fails, but was kind of how I wanted it to be:
type
TFactory = record
class function Manufacture<T: TBaseClass, constructor>(parameter definitions): T;
end;
class function Manufacture<T: TBaseClass, constructor>(parameter definitions): T;
begin
Result := T.Create(parameter values);
end;
Which means I need to update Delphi Constraints in Generics – RAD Studio XE documentation wiki
The factory:
type
TComponentFactory = class
class function CreateComponent<T: TComponent>(AOwner: TComponent): T; static;
end;
class function TComponentFactory.CreateComponent<T>(AOwner: TComponent): T;
var
ComponentClass: TComponentClass;
Component: TComponent;
begin
ComponentClass := T;
Component := ComponentClass.Create(AOwner); // you can't do `T.Create(AOwner)`
Result := T(Component); // you can't do `Result := ComponentClass.Create(AOwner);`
end;
The usage:
var
Component: TButton;
Owner: TComponent;
begin
Owner := Application.MainForm;
Component := TComponentFactory<TButton>.CreateComponent(Owner);
Component.Parent := Owner;
end;
Full source example is at: After a discussion with Stefan Glienke: a pattern for a factory, this one for components, but can be uses for anything having a base class like a TThread descendant.
In the mean time, Spring4D has added the [Archive.is] Spring4D: TActivator record with many CreateInstance methods that allow you to create instances of classes for which you just have type information.
–jeroen
https://gist.github.com/jpluimers/69cee526889de173523ff3d687dc2bfb