Delphi指针,持有泛型类的类的调用函数

时间:2017-04-27 19:42:08

标签: delphi generics

我有一个包含类似通用的Delphi类

type
  TObjectList<T:class, constructor> = class
  private
    FList: Tlist<T>;
  public
    function CreateItem : T;
    function Next : T;
  .
  .
  .
  end;

在我的项目的另一部分中,我需要使用没有T的TObjectList,就像那样

type
  NavControl = class
    _plist:Pointer;
  public 
    constructor Create<T:class,constructor>(list:TObjectList<T>);
  end

如何影响_plist的列表,以及如何从CreateItem致电Next_plist

1 个答案:

答案 0 :(得分:2)

如果您想使用通用类型,则需要存储您在某处使用的通用类型。

但是没有可以容纳type parameter的类型。您必须在类本身中存储T的类型,或者找出其他一些做事方式。

您有两种选择:

推荐选项
Redeclare NavControl就像这样:

type
  TNavControl<T:class, constructor> = class
  private
    _Plist: TObjectList<T>;
  public
     constructor Create(const List: TObjectList<T>);

T中创建NavControl的新实例非常简单:

begin
  NewItem:= T.Create;
  .....

通用和旧图书馆的混搭 - 不推荐 -
另一种方法是识别T是一个对象,因此你可以将它的类存储在TClass类型的变量中,但是为了做到这一点,你必须在你的构造函数中获得一些创意。

type
  TNavControl = class
  private
    _PList: TObjectList<TObject>;
    ClassOfT: TClass;

constructor TNavControl.Create<T:class, constructor>(const List: TObjectList<T>);
var
  Dummy: T;
begin
  Dummy:= T.Create;
  try
    ClassOfT:= TObject(Dummy).ClassType;
  finally
    Dummy.Free;
  end;
end;

您现在必须使用TClass引用来实例化对象,但TClass需要通用约束不会--Oops - 的虚拟构造函数。

我的推荐
就个人而言,我不会在这里打扰泛型 你知道你想要一个班级,你知道你需要一个构造函数 只要构造函数是虚拟的,使用此方法就可以使用带或不带参数的构造函数 只需将对象列表限制为您控制并使用它的合理子类。

type

  TMyClass = class(TControl)
    ...
    constructor Create(const param: string = ''); virtual; <<!!!!
  end;
  TMyClass2 = class(TMyClass)
    constructor Create(const param: string = ''); override <<!!
  end;

  TMyClassClass = class of TMyClass;

  TNavControl = class
  private
    FMyClassClass = TMyClassClass;
    FPList = TObjectList;  //non-generic version
  public
    constructor Create(const ClassType: TMyClassClass); 

  function TNavControl.NewItem(const param: string = ''): TMyClass;
  begin
    Result:= FMyClassClass.Create(param);  //Will create a TMyClass2 or 3
    //Or whatever type you fed into the constructor.
  end;

现在,如果你打电话

 var
   A: TMyClass2;
   B: TMyClass;
   C: TNavControl;

 A:= TMyClass.Create('test');
 C:= TNavControl.Create(A.ClassType);
 B:= C.NewItem('test2');   //Creates a TMyClass2

泛型在使用类时非常有用,最好使用class of ...和虚拟构造函数。
这也允许使用带有参数的构造函数,通用解决方案不能满足这些参数 只需确保始终保持构造函数参数相同。

有关详细信息,请参阅此答案:https://stackoverflow.com/a/758715/650492