方法泛型 Delphi2009初体验-语言篇-体验泛型(二)
Delphi2009初体验-语言篇-体验泛型(二)
六 体验泛型数组
七 体验泛型方法
八 体验自定义泛型类
九 体验泛型约束条件
类类型约束条件
对象类型约束条件
构造函数约束条件
值类型约束条件
多约束条件
多模板类型分别约束条件
嵌套约束条件
十 关于特化与偏特化
十一 总结
由于正式版还没有发出 官方的帮助文档也没有泄露 所以我没有办法验证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 TGeneric PrintAddress<T>(aVal: T); begin Writeln(Integer(@aVal)); end; begin n := ; TGeneric PrintAddress<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(gc Value); 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(gc Value = 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(gc Value = 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 := T Create; 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 TImp Test; begin end; begin gc := TGenericsClass<TImp> Create(nil); Writeln(gc Value = nil); FreeAndNil(gc ); Readln; end 多模板类型分别约束条件
有两个模板类型T T 要使用不同的约束分别约束两个模板类型 可以使用以下方法 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的默认值(值类型置 引用类型为空指针)
lishixinzhi/Article/program/Delphi/201311/24664