六体验泛型数组
七体验泛型方法
八体验自定义泛型类
九体验泛型约束条件
类类型约束条件
对象类型约束条件
构造函数约束条件
值类型约束条件
多约束条件
多模板类型分别约束条件
嵌套约束条件
十关于特化与偏特化
十一 总结
由于正式版还没有发出官方的帮助文档也没有洩露所以我没有办法验证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更强大)的支持