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

本文通过实际代码演示了Delphi 2009中泛型的使用方法,包括泛型数组、方法、自定义泛型类及各种泛型约束条件,并探讨了特化与偏特化的问题。

 快速导航

六、体验泛型数组

七、体验泛型方法

八、体验自定义泛型类

九、体验泛型约束条件

1、类类型约束条件

2、对象类型约束条件

3、构造函数约束条件

4、值类型约束条件

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

7、嵌套约束条件

 十、关于特化与偏特化

 十一、 总结

 

 


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

 六、体验泛型数组

 1 program  TestGenericArray;
 2
 3 { $APPTYPE CONSOLE }
 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、以下代码将打印出传入泛型变量的地址:
 

 1 program  TestGenericArray;
 2
 3 { $APPTYPE CONSOLE }
 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 .

 

 

 八、体验自定义泛型类

 1 program  TestGenericClass;
 2
 3 { $APPTYPE CONSOLE }
 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只能为类类型

 1 program  TestGenericClass;
 2
 3 { $APPTYPE CONSOLE }
 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只能为某一个对象类型

 

 1 program  TestGenericArray;
 2
 3 { $APPTYPE CONSOLE }
 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中,我也发现有这样的特性:

 

1 TGeneric < T:  constructor >   =   class
2 public
3      constructor  Create;  virtual ;
4 end ;

 

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

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

 

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既满足一个类型,又满足一个接口。

 

 1 program  TestGenericArray;
 2
 3 { $APPTYPE CONSOLE }
 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,要使用不同的约束分别约束两个模板类型,可以使用以下方法:

1 type
2     TGenericsClass < T:  class ; T1: TList >   =   class    //  注意在此进行约束,用“;”将两个模板类型分开进行分别约束
3      private
4      end ;
 7、嵌套约束条件

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

 

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、付费专栏及课程。

余额充值