簡體   English   中英

Delphi指針,持有泛型的類的調用函數

[英]Delphi pointer, call function of class that hold a generic type

我有一個像這樣的通用類的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列表,以及如何從_plist調用CreateItemNext

如果要使用泛型類型,則需要將正在使用的泛型類型存儲在某個地方。

但是,沒有可以容納type parametertype parameter 您要么必須將T的類型存儲在類本身中,要么要找出其他處理方式。

您有兩種選擇:

推薦選項
像這樣重新NavControl

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

NavControl創建T新實例很容易:

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 ...和虛擬構造函數的class of ...
這也允許使用帶有參數的構造函數,而通用解決方案則無法滿足這些參數。
只要確保在整個過程中構造函數的參數都相同即可。

請參閱此答案以獲取更多信息: https : //stackoverflow.com/a/758715/650492

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM