I am trying to create a common ancestor for composite controls. The initial idea looked something like this:
type
TCompositeControl<TControl1: TControl; TControl2: TControl> = class(TWinControl)
private
FControl1,
FControl2: TControl;
public
constructor Create(AOwner: TComponent); override;
end;
TLabelAndEdit = TCompositeControl<TLabel, TEdit>; // simple example for illustration only
constructor TCompositeControl<TControl1,TControl2>.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FControl1 := TControl1.Create(Self);
FControl2 := TControl2.Create(Self);
end;
As you already know, this will cause an E2568 compiler error: it is not possible to create a new instance without the CONSTRUCTOR constraint in the type parameter declaration. Adding a constraint constructordoes not help, since it implies a constructor without parameters.
Casting templates into TControlcompiled code makes:
...
FControl1 := TControl(TControl1).Create(Self);
...
... but this leads to an access violation at runtime.
One hack that is likely to work calls the constructor via RTTI, but I would find this a rather dirty solution.
, , :
type
TControlClass = class of TControl;
constructor TCompositeControl<TControl1,TControl2>.Create(AOwner: TComponent);
var
lCtrlClass1,
lCtrlClass2: TControlClass;
begin
inherited Create(AOwner);
lCtrlClass1 := TControl1;
FControl1 := lCtrlClass1.Create(Self);
lCtrlClass2 := TControl2;
FControl2 := lCtrlClass2.Create(Self);
end;
? , - , classtype-constraint ?