1. 程式人生 > >Delphi之引數化型別(泛型)

Delphi之引數化型別(泛型)

Delphi做容器比較不方便的地方就是沒有泛型,也就是引數化型別.

例如TList裡面每一項是TForm.那麼Delphi就不能使用List[I].Show();這樣的方法.而必須做型別轉換.

TForm(List[I]).Show();

雖說一樣能實現,但是畢竟麻煩.C++正是因為支援泛型才有的模板庫.

Rad Studi 2007的Delphi.NET已經開始支援泛型了.這個我不太感興趣,我感興趣的是Delphi Win32對泛型的支援.

根據Code Gear釋出的Delphi路線圖.Delphi Win32在2008上半年發行的版本里會支援泛型.

不過我們到時可以用Delphi2007.NET先預覽一下Delphi對泛型的語法支援是怎樣的.

查了一下CodeGear上面的官方說法.不過給出的例子語法很多地方都不對.自己琢磨了很久才出正確的.CodeGear這態度太"認真"了.

type
  TGenericList <T> = class
  private
    FData : array of T;
    function GetItem(Index: Integer): T;
  public
    Function Add(Item : T):Integer;
    function GetCount: Integer;
    procedure Delete();
    Procedure Clear();


    property Count : Integer Read GetCount;
    property Item[Index : Integer] : T read GetItem;default;
  end;

function TGenericList<T>.Add(Item: T): Integer;
begin
  Result := Count;
  SetLength(FData, Result + 1);
  FData[Result] := Item;
end;

procedure TGenericList<T>.Clear;
begin
  //懶得寫了
end;

procedure TGenericList<T>.Delete;
begin
  //懶得寫了
end;

function TGenericList<T>.GetCount: Integer;
begin
  Result := 0;
  if FData = nil then
    Exit;
  Result := Length(FData);

end;

function TGenericList<T>.GetItem(Index: Integer): T;
begin
  Result := FData[Index];
end;

使用的時候

var
  ButtonList : TGenericList<TButton>;
  I : Integer;
begin
  ButtonList := TGenericList<TButton>.Create();

  for I := 0 to 3 do
  begin
    ButtonList.Add(TButton.Create(Self));
    ButtonList[I].Caption := IntToStr(I);
    ButtonList[I].Top := ButtonList[I].Height*I;
    ButtonList[I].Parent := Self;
  end;

  ButtonList.Free();
end;

至於Delphi的泛型是像C++,Java那樣基於原始碼替換機制還是像.NET那樣的基於執行時資訊的我就沒有細看.畢竟我對IL ASM不是特別熟悉.估計Delphi.NET可能是和C#一樣基於執行時吧.那麼Delphi Win32呢?難道也是基於執行時?畢竟這樣的話還要新增一些執行時的資訊.如果是基於原始碼替換規則,那麼DCU檔案還要重新編譯嗎?畢竟C++的泛型OBJ,LIB檔案不用編譯,因為它有帶原始碼的標頭檔案.不去想了

呵呵,在登上幾個月.2008年上半年釋出的Delphi for Win32也會具有這樣的方便語法.