Oli*_*sen 5 delphi generics polymorphism constructor generic-constraints
我正在尝试为复合控件构建一个通用的祖先.最初的想法看起来像这样:
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;
Run Code Online (Sandbox Code Playgroud)
您可能已经知道,这将触发编译器错误E2568:无法在类型参数声明中创建没有CONSTRUCTOR约束的新实例.constructor然而,添加约束并没有帮助,因为它意味着无参数构造函数.
转换模板以TControl使代码可编译:
...
FControl1 := TControl(TControl1).Create(Self);
...
Run Code Online (Sandbox Code Playgroud)
...但它会在运行时导致访问冲突.
一个可能有用的黑客是通过RTTI调用构造函数,但我认为这是一个相当脏的解决方案.
另一个基本上有效的黑客是使用类类型变量作为中间体:
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;
Run Code Online (Sandbox Code Playgroud)
有更清洁的解决方案吗?另外,有人可以向我解释为什么classtype-constraint不足以直接调用type参数上的虚构造函数吗?
你的类型很糟糕:TControl(TControl1).Create(Self).这告诉编译器TControl1就是一个实例的TControl,但我们知道,这不是一个实例.这是一个类引用.将其类型转换为类引用类型:
FControl1 := TControlClass(TControl1).Create(Self);
Run Code Online (Sandbox Code Playgroud)