加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi XE:我是否可以使用classtype约束泛型类型的参数调用虚拟

发布时间:2020-12-15 09:28:05 所属栏目:大数据 来源:网络整理
导读:我正在尝试为复合控件构建一个通用的祖先.最初的想法看起来像这样: type TCompositeControlTControl1: TControl; TControl2: TControl = class(TWinControl) private FControl1,FControl2: TControl; public constructor Create(AOwner: TComponent); overr
我正在尝试为复合控件构建一个通用的祖先.最初的想法看起来像这样:

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;

有更清洁的解决方案吗?另外,有人可以向我解释为什么classtype-constraint不足以直接调用type参数上的虚构造函数吗?

解决方法

你的类型转换是坏的:TControl(TControl1).Create(Self).这告诉编译器TControl1是TControl的一个实例,但我们知道它不是一个实例.这是一个类引用.将其类型转换为类引用类型:

FControl1 := TControlClass(TControl1).Create(Self);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读