快速导航
六、体验泛型数组
七、体验泛型方法
八、体验自定义泛型类
九、体验泛型约束条件
1、类类型约束条件
2、对象类型约束条件
3、构造函数约束条件
4、值类型约束条件
5、多约束条件
6、多模板类型分别约束条件7、嵌套约束条件
十、关于特化与偏特化
十一、 总结
由于正式版还没有发出,官方的帮助文档也没有泄露,所以我没有办法验证Delphi对泛型的支持到何种程度了。大家对泛型都很熟悉,具体细节我就不多说了。下面将贴出一些代码,用来验证Delphi对泛型的支持并验证是否通过。
六、体验泛型数组
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、以下代码将打印出传入泛型变量的地址:
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
.

八、体验自定义泛型类
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只能为类类型
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只能为某一个对象类型
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中,我也发现有这样的特性:
TGeneric
<
T:
constructor
>
=
class
2
public
3
constructor
Create;
virtual
;4
end
;
约束“: constructor”表明T必须拥有可见的构造函数。
但是,我在使用以下代码时,编译器总是提示编译不通过:
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既满足一个类型,又满足一个接口。
program
TestGenericArray;2

3
{
$APPTYPE CONSOLE
}
4

5
uses
6
SysUtils,7
Classes,8
Windows,9
Contnrs;10

11
type
12
IInt
=
Interface13
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,要使用不同的约束分别约束两个模板类型,可以使用以下方法:
type
2
TGenericsClass
<
T:
class
; T1: TList
>
=
class
//
注意在此进行约束,用“;”将两个模板类型分开进行分别约束3
private
4
end
;
7、嵌套约束条件
Delphi2009的泛型约束条件对嵌套约束条件处理的很好,如:
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更强大)的支持。
本文通过实际代码演示了Delphi 2009中泛型的使用方法,包括泛型数组、方法、自定义泛型类及各种泛型约束条件,并探讨了特化与偏特化的问题。
167

被折叠的 条评论
为什么被折叠?



