Delphi2009初体验 - 语言篇 - 体验泛型(二)

快速导航

六、体验泛型数组

七、体验泛型方法

八、体验自定义泛型类

九、体验泛型约束条件

1、类类型约束条件

2、对象类型约束条件

3、构造函数约束条件

4、值类型约束条件

5、多约束条件
6、多模板类型分别约束条件

7、嵌套约束条件

十、关于特化与偏特化

十一、 总结


由于正式版还没有发出,官方的帮助文档也没有泄露,所以我没有办法验证Delphi对泛型的支持到何种程度了。大家对泛型都很熟悉,具体细节我就不多说了。下面将贴出一些代码,用来验证Delphi对泛型的支持并验证是否通过。

六、体验泛型数组

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 program TestGenericArray;
2
3 { $APPTYPECONSOLE }
4
5 uses
6 SysUtils;
7
8 type
9 TArr < T > = array of T;
10
11 var
12 arr:TArr < Integer > ;
13 n:Integer;
14 begin
15 Setlength(arr, 10 );
16
17 for n: = 0 to 9 do
18 begin
19 arr[n]: = n;
20 end ;
21 end .
22

七、体验泛型方法

1、Delphi2009不支持全局泛型方法,泛型方法只能置于类内或者嵌套在方法内,或者成为类的静态方法。
2、以下代码将打印出传入泛型变量的地址:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 program TestGenericArray;
2
3 { $APPTYPECONSOLE }
4
5 uses
6 SysUtils;
7
8 type
9 TGeneric = class
10 class procedure PrintAddress < T > (aVal:T);
11 end ;
12
13 var
14 n:Integer;
15
16 { TGeneric }
17
18 class procedure TGeneric.PrintAddress < T > (aVal:T);
19 begin
20 Writeln(Integer(@aVal));
21 end ;
22
23 begin
24 n: = 10 ;
25 TGeneric.PrintAddress < Integer > (n);
26 end .

八、体验自定义泛型类

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 program TestGenericClass;
2
3 { $APPTYPECONSOLE }
4
5 uses
6 SysUtils;
7
8 type
9 TGenericsClass1 < T > = class
10 private
11 fValue:T;
12 public
13 constructor Create(aValue:T); virtual ;
14 property Value:T read fValue write fValue;
15 end ;
16
17 var
18 gc1:TGenericsClass1 < Integer > ;
19
20 { TGenericsClass1<T> }
21
22 constructor TGenericsClass1 < T > .Create(aValue:T);
23 begin
24 fValue: = aValue;
25 end ;
26
27 begin
28 gc1: = TGenericsClass1 < Integer > .Create( 10 );
29 Writeln(gc1.Value);
30 FreeAndNil(gc1);
31
32 Readln;
33 end .

九、体验泛型约束条件

以下通过代码针对泛型类,对Delphi2009所支持的泛型约束条件进行验证。

1、类类型约束条件

约束模板类型T只能为类类型

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 program TestGenericClass;
2
3 { $APPTYPECONSOLE }
4
5 uses
6 SysUtils;
7
8 type
9 TGenericsClass1 < T: class > = class // 注意在此进行约束
10 private
11 fValue:T;
12 public
13 constructor Create(aValue:T); virtual ;
14 property Value:T read fValue write fValue;
15 end ;
16
17 var
18 gc1:TGenericsClass1 < TObject > ;
19
20 { TGenericsClass1<T> }
21
22 constructor TGenericsClass1 < T > .Create(aValue:T);
23 begin
24 fValue: = aValue;
25 end ;
26
27 begin
28 gc1: = TGenericsClass1 < TObject > .Create( nil );
29 Writeln(gc1.Value = nil );
30 FreeAndNil(gc1);
31
32 Readln;
33 end .

2、对象类型约束条件

约束T只能为某一个对象类型

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 program TestGenericArray;
2
3 { $APPTYPECONSOLE }
4
5 uses
6 SysUtils,
7 Classes,
8 Contnrs;
9
10 type
11 TGenericsClass1 < T:TList > = class // 注意在此进行约束
12 private
13 fValue:T;
14 public
15 constructor Create(aValue:T); virtual ;
16 property Value:T read fValue write fValue;
17 end ;
18
19 var
20 gc1:TGenericsClass1 < TObjectList > ;
21
22 { TGenericsClass1<T> }
23
24 constructor TGenericsClass1 < T > .Create(aValue:T);
25 begin
26 fValue: = aValue;
27 end ;
28
29 begin
30 gc1: = TGenericsClass1 < TObjectList > .Create( nil );
31 Writeln(gc1.Value = nil );
32 FreeAndNil(gc1);
33
34 Readln;
35 end .

3、构造函数约束条件

大家都知道,在C#中,可以使用 T: where new() 对泛型模板类型进行构造函数的约束,指明 类型T 必须有一个可见的构造函数。

在D2009中,我也发现有这样的特性:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 TGeneric < T: constructor > = class
2 public
3 constructor Create; virtual ;
4 end ;

约束“: constructor”表明T必须拥有可见的构造函数。

但是,我在使用以下代码时,编译器总是提示编译不通过:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 var
2 t:T;
3 begin
4 t: = T.Create;
5 end ;

获取是另外一种写法?我没有尝试出来,需要等官方正式版出来才能确认。

4、值类型约束条件

Delphi2009的泛型约束不提供值类型约束条件,TGenericsClass1<T: Integer> = class这样的约束编译器是不支持的。所以,像c++中template <Tint S> class TBuf这样的约束在Delphi中行不通。

5、多约束条件

与C#类似,Delphi2009的多约束条件用来约束T既满足一个类型,又满足一个接口。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 program TestGenericArray;
2
3 { $APPTYPECONSOLE }
4
5 uses
6 SysUtils,
7 Classes,
8 Windows,
9 Contnrs;
10
11 type
12 IInt = Interface
13 procedure Test;
14 End;
15
16 TImp = class (TInterfacedObject,IInt)
17 public
18 procedure Test;
19 end ;
20
21 TGenericsClass < T: class ,IInt > = class // 注意在此进行约束
22 private
23 fValue:T;
24 public
25 constructor Create(aValue:T); virtual ;
26 property Value:T read fValue write fValue;
27 end ;
28
29 var
30 gc1:TGenericsClass < TImp > ;
31
32 { TGenericsClass<T> }
33
34 constructor TGenericsClass < T > .Create(aValue:T);
35 begin
36 fValue: = aValue;
37 end ;
38
39 { TImp }
40
41 procedure TImp.Test;
42 begin
43
44 end ;
45
46 begin
47 gc1: = TGenericsClass < TImp > .Create( nil );
48 Writeln(gc1.Value = nil );
49 FreeAndNil(gc1);
50
51 Readln;
52 end .
6、多模板类型分别约束条件

有两个模板类型T1、T2,要使用不同的约束分别约束两个模板类型,可以使用以下方法:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 type
2 TGenericsClass < T: class ;T1:TList > = class // 注意在此进行约束,用“;”将两个模板类型分开进行分别约束
3 private
4 end ;
7、嵌套约束条件

Delphi2009的泛型约束条件对嵌套约束条件处理的很好,如:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 TFelix < T > = class
2 public
3
4 end ;
5
6 TGenericsClass < T: class ;T1:TFelix < T >> = class // 注意在此进行约束,用“;”将两个模板类型分开进行分别约束
7 private
8 end ;

十、关于特化和偏特化

谢谢网友“装配脑袋”的提醒,我试了很多方法,都没有迹象表明D2009支持C++中模板的特化和偏特化,或者D2009用其他形式的语法表示特化与偏特化,导致我没有试验出来。

十一、总结

总体上来说,D2009从泛型的角度出发,做得已经非常不错了,已经非常接近C#。甚至,D2009还提供类似于C#的关键字“default”,来获取泛型类型T的默认值(值类型置0,引用类型为空指针)。

在接下来的章节里,我会向大家介绍D2009的其他新体验,如:匿名函数和反射(比RTTI更强大)的支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值