Delphi指针,包含泛型类型的类的调用函数

Delphi指针,包含泛型类型的类的调用函数,delphi,generics,Delphi,Generics,我有一个Delphi类,它包含这样一个泛型 type TObjectList<T:class, constructor> = class private FList: Tlist<T>; public function CreateItem : T; function Next : T; . . . end; 类型 TObjectList=类 私有的 FList:Tlist; 平民的 函数CreateItem:T; 函

我有一个Delphi类,它包含这样一个泛型

type
  TObjectList<T:class, constructor> = class
  private
    FList: Tlist<T>;
  public
    function CreateItem : T;
    function Next : T;
  .
  .
  .
  end;
类型
TObjectList=类
私有的
FList:Tlist;
平民的
函数CreateItem:T;
函数Next:T;
.
.
.
终止
在我项目的另一部分中,我需要使用不带T的TObjectList,就像这样

type
  NavControl = class
    _plist:Pointer;
  public 
    constructor Create<T:class,constructor>(list:TObjectList<T>);
  end
类型
导航控制=类
_plist:指针;
平民的
构造函数创建(列表:TObjectList);
终止

如何将列表影响到
\u plist
,以及如何从
\u plist
调用
CreateItem
下一步

如果要使用泛型类型,需要将正在使用的泛型类型存储在某处

但是,没有可以保存
类型参数的类型。您要么必须将
T
的类型存储在类本身中,要么找出其他方法

您有两个选择:

推荐选项
重新声明
NavControl
如下:

type
  TNavControl<T:class, constructor> = class
  private
    _Plist: TObjectList<T>;
  public
     constructor Create(const List: TObjectList<T>);
通用和旧skool混搭-不推荐使用-
另一种方法是认识到
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;
现在如果你打电话

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

 A:= TMyClass.Create('test');
 C:= TNavControl.Create(A.ClassType);
 B:= C.NewItem('test2');   //Creates a TMyClass2
泛型在处理类时没有多大用处,最好使用…
类和虚拟构造函数。
这也允许使用具有参数的构造函数,而一般解决方案不满足这些参数。
只需确保构造函数参数始终保持不变


有关更多信息,请参见此答案:

为什么
\u plist
是非类型的
指针?它需要是一个
TObjetcList
,这将需要将泛型参数从
Create
移动到
NavControl
。如果您将just
Create
设置为Generic,您将无法稍后键入cast
\u plist
,因为您不知道传递给
Create
t
是什么。NavControl是singlton???,因此,我不能使用Generic,所有列表都需要控制(添加、删除,…)仅从一个具有激活的corse witch used list的位置开始。显示的代码中没有任何内容将
NavControl
限制为单例。但即使是单身,这也不会改变我所说的。如果将
\u plist
保留为
指针
,则必须在需要访问其成员时键入cast,如果不知道它是什么类型,则无法键入cast,并且无法使用传递给
Create
t
,因为它仅为
Create
而存在。你需要重新思考你的方法。特别是如果
NavControl
是一个单例,没有理由不能将
t
参数移到
NavControl
而不是
Create
,那么就可以给
\u plist
一个合适的类型。我需要尽量避免将TNavControl设置为泛型,其他部分、接口似乎都是完美的选择(TObjectList实现了一些接口)并且我所有的代码都使用该接口调用TNavControl(是singlton)。很抱歉没有很好地描述我的问题。@webmaster:那么请你的问题来说明你想如何使用
NavControl
,以便有人能告诉你如何正确地使用它,或者更好地使用它。
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