• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 快速导航

六、体验泛型数组

七、体验泛型方法

八、体验自定义泛型类

九、体验泛型约束条件

1、类类型约束条件

2、对象类型约束条件

3、构造函数约束条件

4、值类型约束条件

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

7、嵌套约束条件

 十、关于特化与偏特化

 十一、 总结

 

 


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

 六、体验泛型数组

 1program TestGenericArray;
 2
 3{$APPTYPE CONSOLE}
 4
 5uses
 6    SysUtils;
 7
 8type
 9    TArr<T> = array of T;
10
11var
12    arr: TArr<Integer>;
13    n: Integer;
14begin
15    Setlength(arr, 10);
16
17    for n := 0 to 9 do
18    begin
19        arr[n] := n;
20    end;
21end.
22

七、体验泛型方法

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

 1program TestGenericArray;
 2
 3{$APPTYPE CONSOLE}
 4
 5uses
 6    SysUtils;
 7
 8type
 9    TGeneric = class
10        class procedure PrintAddress<T>(aVal: T);
11    end;
12
13var
14    n: Integer;
15
16{ TGeneric }
17
18class procedure TGeneric.PrintAddress<T>(aVal: T);
19begin
20    Writeln(Integer(@aVal));
21end;
22
23begin
24    n := 10;
25    TGeneric.PrintAddress<Integer>(n);
26end.

 

 

 八、体验自定义泛型类

 1program TestGenericClass;
 2
 3{$APPTYPE CONSOLE}
 4
 5uses
 6  SysUtils;
 7
 8type
 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
17var
18    gc1: TGenericsClass1<Integer>;
19
20{ TGenericsClass1<T> }
21
22constructor TGenericsClass1<T>.Create(aValue: T);
23begin
24    fValue := aValue;
25end;
26
27begin
28    gc1 := TGenericsClass1<Integer>.Create(10);
29    Writeln(gc1.Value);
30    FreeAndNil(gc1);
31
32    Readln;
33end.

 

 

 九、体验泛型约束条件

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

1、类类型约束条件

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

 1program TestGenericClass;
 2
 3{$APPTYPE CONSOLE}
 4
 5uses
 6    SysUtils;
 7
 8type
 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
17var
18    gc1: TGenericsClass1<TObject>;
19
20{ TGenericsClass1<T> }
21
22constructor TGenericsClass1<T>.Create(aValue: T);
23begin
24    fValue := aValue;
25end;
26
27begin
28    gc1 := TGenericsClass1<TObject>.Create(nil);
29    Writeln(gc1.Value = nil);
30    FreeAndNil(gc1);
31
32    Readln;
33end.

 

 2、对象类型约束条件

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

 

 1program TestGenericArray;
 2
 3{$APPTYPE CONSOLE}
 4
 5uses
 6    SysUtils,
 7    Classes,
 8    Contnrs;
 9
10type
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
19var
20    gc1: TGenericsClass1<TObjectList>;
21
22{ TGenericsClass1<T> }
23
24constructor TGenericsClass1<T>.Create(aValue: T);
25begin
26    fValue := aValue;
27end;
28
29begin
30    gc1 := TGenericsClass1<TObjectList>.Create(nil);
31    Writeln(gc1.Value = nil);
32    FreeAndNil(gc1);
33
34    Readln;
35end.

 

 3、构造函数约束条件

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

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

 

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

 

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

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

 

1var
2    t: T;
3begin
4    t := T.Create;
5end;

 

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

 4、值类型约束条件

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

 5、多约束条件

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

 

 1program TestGenericArray;
 2
 3{$APPTYPE CONSOLE}
 4
 5uses
 6    SysUtils,
 7    Classes,
 8    Windows,
 9    Contnrs;
10
11type
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
29var
30    gc1: TGenericsClass<TImp>;
31
32{ TGenericsClass<T> }
33
34constructor TGenericsClass<T>.Create(aValue: T);
35begin
36    fValue := aValue;
37end;
38
39{ TImp }
40
41procedure TImp.Test;
42begin
43
44end;
45
46begin
47    gc1 := TGenericsClass<TImp>.Create(nil);
48    Writeln(gc1.Value = nil);
49    FreeAndNil(gc1);
50
51    Readln;
52end.

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

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

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

 7、嵌套约束条件

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

 

1TFelix<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更强大)的支持。

 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Matlab系列作业发布时间:2022-07-18
下一篇:
matlab第一次作业发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap