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

Delphi泛型:如何规范“引用自己类型的类”

发布时间:2020-12-15 09:26:01 所属栏目:大数据 来源:网络整理
导读:在Delphi XE2中,我想编写一个泛型集合类来操作必须具有Copy(owntype)方法的对象,但我无法弄清楚如何最好地声明它. 我想要这样的例子(一个项目的集合,为简单起见): //------ Library ------Type TBaseCopyable = class S: string;// procedure Copy(OtherObj
在Delphi XE2中,我想编写一个泛型集合类来操作必须具有Copy(owntype)方法的对象,但我无法弄清楚如何最好地声明它.

我想要这样的例子(一个项目的集合,为简单起见):

//------ Library ------
Type
  TBaseCopyable = class
    S: string;
//    procedure Copy(OtherObject: TBaseCopyable); overload;
    procedure Copy(OtherObject: TBaseCopyable); virtual;
  end;

  MyCollection<T: TBaseCopyable,constructor> = class
    TheItem: T;
    procedure SetItem(AItem: T); 
    function  GetItem: T;
  end;

[...]

function MyCollection<T>.GetItem: T;
Var
  NewItem: T;
begin
  NewItem := T.Create;
  NewItem.Copy(TheItem);
  Result := NewItem;
end;


//------ Usage ------
Type
  TMyCopyable = class(TBaseCopyable)
    I: integer;
//  procedure Copy(OtherObject: TMyCopyable); overload;
    procedure Copy(OtherObject: TMyCopyable); override;
  end;

[...]
  Col: MyCollection<TMyCopyable>;

关键问题是在Col中,我需要MyCollection的通用实现来查找TMyCopyable.Copy.不出所料,过载或虚拟都不能完成工作:

>有了重载,代码会编译,但MyCollection.GetItem会找到
TBaseCopyable.Copy,而不是TMyCopyable.Copy.
>使用虚拟/覆盖此功能
因为两个Copy声明的签名而无法编译
不匹配.

所以我想我需要在TBaseCopyable的规范中以某种方式使用泛型,可能代替继承.但我不确定如何,主要是因为我不特别需要将类型参数提供给TBaseCopyable,我只需要复制参数类型以通用方式引用“它自己类的类型”.

想法?谢谢!

解决方法

将TBaseCopyable转换为Generic类并将其Generic类型应用于Copy(),然后TMyCopyable可以覆盖它,例如:

type
  TBaseCopyable<T> = class
    S: string;
    procedure Copy(OtherObject: T); virtual;
  end;

  MyCollection<T: TBaseCopyable<T>,constructor> = class
    TheItem: T;
    procedure SetItem(AItem: T);
    function  GetItem: T;
  end;
type
  TMyCopyable = class(TBaseCopyable<TMyCopyable>)
    I: integer;
    procedure Copy(OtherObject: TMyCopyable); override;
  end;

或者,只做TPersistent.Assign()所做的事情(因为它不使用Generics):

type
  TBaseCopyable = class
    S: string;
    procedure Copy(OtherObject: TBaseCopyable); virtual;
  end;

  MyCollection<T: TBaseCopyable,constructor> = class
    TheItem: T;
    procedure SetItem(AItem: T);
    function  GetItem: T;
  end;
type
  TMyCopyable = class(TBaseCopyable)
    I: integer;
    procedure Copy(OtherObject: TBaseCopyable); override;
  end;

procedure TMyCopyable.Copy(OtherObject: TBaseCopyable);
begin
  inherited;
  if OtherObject is TMyCopyable then
    I := TMyCopyable(OtherObject).I;
end;

(编辑:李大同)

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

    推荐文章
      热点阅读