六體驗泛型數組
七體驗泛型方法
八體驗自定義泛型類
九體驗泛型約束條件
類類型約束條件
對象類型約束條件
構造函數約束條件
值類型約束條件
多約束條件
多模板類型分別約束條件
嵌套約束條件
十關於特化與偏特化
十一 總結
由於正式版還沒有發出官方的幫助文檔也沒有洩露所以我沒有辦法驗證Delphi對泛型的支持到何種程度了大家對泛型都很熟悉具體細節我就不多說了下面將貼出一些代碼用來驗證Delphi對泛型的支持並驗證是否通過
六體驗泛型數組
program TestGenericArray;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TArr<T> = array of T;
var
arr: TArr<Integer>;
n: Integer;
begin
Setlength(arr );
for n := to do
begin
arr[n] := n;
end;
end
七體驗泛型方法
Delphi不支持全局泛型方法泛型方法只能置於類內或者嵌套在方法內或者成為類的靜態方法
以下代碼將打印出傳入泛型變量的地址
program TestGenericArray;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TGeneric = class
class procedure PrintAddress<T>(aVal: T);
end;
var
n: Integer;
{ TGeneric }
class procedure TGenericPrintAddress<T>(aVal: T);
begin
Writeln(Integer(@aVal));
end;
begin
n := ;
TGenericPrintAddress<Integer>(n);
end
八體驗自定義泛型類
program TestGenericClass;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TGenericsClass<T> = class
private
fValue: T;
public
constructor Create(aValue: T); virtual;
property Value: T read fValue write fValue;
end;
var
gc: TGenericsClass<Integer>;
{ TGenericsClass<T> }
constructor TGenericsClass<T>Create(aValue: T);
begin
fValue := aValue;
end;
begin
gc := TGenericsClass<Integer>Create();
Writeln(gcValue);
FreeAndNil(gc);
Readln;
end
九體驗泛型約束條件
以下通過代碼針對泛型類對Delphi所支持的泛型約束條件進行驗證
類類型約束條件
約束模板類型T只能為類類型
program TestGenericClass;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TGenericsClass<T: class> = class // 注意在此進行約束
private
fValue: T;
public
constructor Create(aValue: T); virtual;
property Value: T read fValue write fValue;
end;
var
gc: TGenericsClass<TObject>;
{ TGenericsClass<T> }
constructor TGenericsClass<T>Create(aValue: T);
begin
fValue := aValue;
end;
begin
gc := TGenericsClass<TObject>Create(nil);
Writeln(gcValue = nil);
FreeAndNil(gc);
Readln;
end
對象類型約束條件
約束T只能為某一個對象類型
program TestGenericArray;
{$APPTYPE CONSOLE}
uses
SysUtils
Classes
Contnrs;
type
TGenericsClass<T: TList> = class // 注意在此進行約束
private
fValue: T;
public
constructor Create(aValue: T); virtual;
property Value: T read fValue write fValue;
end;
var
gc: TGenericsClass<TObjectList>;
{ TGenericsClass<T> }
constructor TGenericsClass<T>Create(aValue: T);
begin
fValue := aValue;
end;
begin
gc := TGenericsClass<TObjectList>Create(nil);
Writeln(gcValue = nil);
FreeAndNil(gc);
Readln;
end
構造函數約束條件
大家都知道在C#中可以使用 T where new() 對泛型模板類型進行構造函數的約束指明 類型T 必須有一個可見的構造函數
在D中我也發現有這樣的特性
TGeneric<T: constructor> = class
public
constructor Create; virtual;
end;
約束 constructor表明T必須擁有可見的構造函數
但是我在使用以下代碼時編譯器總是提示編譯不通過
var
t: T;
begin
t := TCreate;
end;
獲取是另外一種寫法?我沒有嘗試出來需要等官方正式版出來才能確認
值類型約束條件
Delphi的泛型約束不提供值類型約束條件TGenericsClass<T Integer> = class這樣的約束編譯器是不支持的所以像c++中template <Tint S> class TBuf這樣的約束在Delphi中行不通
多約束條件
與C#類似Delphi的多約束條件用來約束T既滿足一個類型又滿足一個接口
program TestGenericArray;
{$APPTYPE CONSOLE}
uses
SysUtils
Classes
Windows
Contnrs;
type
IInt = Interface
procedure Test;
End;
TImp = class(TInterfacedObject IInt)
public
procedure Test;
end;
TGenericsClass<T: class IInt> = class // 注意在此進行約束
private
fValue: T;
public
constructor Create(aValue: T); virtual;
property Value: T read fValue write fValue;
end;
var
gc: TGenericsClass<TImp>;
{ TGenericsClass<T> }
constructor TGenericsClass<T>Create(aValue: T);
begin
fValue := aValue;
end;
{ TImp }
procedure TImpTest;
begin
end;
begin
gc := TGenericsClass<TImp>Create(nil);
Writeln(gcValue = nil);
FreeAndNil(gc);
Readln;
end
多模板類型分別約束條件
有兩個模板類型TT要使用不同的約束分別約束兩個模板類型可以使用以下方法
type
TGenericsClass<T: class; T: TList> = class // 注意在此進行約束用將兩個模板類型分開進行分別約束
private
end;
嵌套約束條件
Delphi的泛型約束條件對嵌套約束條件處理的很好如
TFelix<T> = class
public
end;
TGenericsClass<T: class; T: TFelix<T>> = class // 注意在此進行約束用將兩個模板類型分開進行分別約束
private
end;
十關於特化和偏特化
謝謝網友裝配腦袋的提醒我試了很多方法都沒有跡象表明D支持C++中模板的特化和偏特化或者D用其他形式的語法表示特化與偏特化導致我沒有試驗出來
十一總結
總體上來說D從泛型的角度出發做得已經非常不錯了已經非常接近C#甚至D還提供類似於C#的關鍵字default來獲取泛型類型T的默認值(值類型置引用類型為空指針)
在接下來的章節裡我會向大家介紹D的其他新體驗如匿名函數和反射(比RTTI更強大)的支持
From:http://tw.wingwit.com/Article/program/Delphi/201311/24664.html