作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为复合控件构建一个通用祖先。最初的想法是这样的:
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;
您可能已经知道,这将触发编译器错误 E2568:无法在类型参数声明中没有 CONSTRUCTOR 约束的情况下创建新实例。但是,添加构造函数约束并没有帮助,因为它意味着无参数构造函数。
将模板转换为 TControl
使代码可编译:
...
FControl1 := TControl(TControl1).Create(Self);
...
...但它会导致运行时访问冲突。
一个可能有效的技巧是通过 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;
有更清洁的解决方案吗?另外,有人可以向我解释为什么类类型约束不足以直接在类型参数上调用虚拟构造函数吗?
最佳答案
你的类型转换不好:TControl(TControl1).Create(Self)
。这告诉编译器 TControl1
是 TControl
的实例,但我们知道它不是一个实例。这是一个类引用。将其类型转换为类引用类型:
FControl1 := TControlClass(TControl1).Create(Self);
关于德尔福XE : Can I call virtual constructors with parameters from a classtype-constrained generic type without resigning to hacks?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9586626/
我是一名优秀的程序员,十分优秀!