快速导航

六、体验泛型数组

七、体验泛型方法

八、体验自定义泛型类

九、体验泛型约束条件

1、类类型约束条件

2、对象类型约束条件

3、构造函数约束条件

4、值类型约束条件

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

7、嵌套约束条件

 十、关于特化与偏特化

 十一、 总结

 

 


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

 六、体验泛型数组

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

七、体验泛型方法

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

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

 

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

 八、体验自定义泛型类

 1(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)program TestGenericClass;
 2(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 3(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二){$APPTYPE CONSOLE}
 4(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 5(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)uses
 6(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)  SysUtils;
 7(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 8(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)type
 9(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    TGenericsClass1<T> = class
10(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    private
11(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        fValue: T;
12(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    public
13(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        constructor Create(aValue: T); virtual;
14(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        property Value: T read fValue write fValue;
15(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    end;
16(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
17(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)var
18(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    gc1: TGenericsClass1<Integer>;
19(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
20(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二){ TGenericsClass1<T> }
21(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
22(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)constructor TGenericsClass1<T>.Create(aValue: T);
23(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
24(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    fValue := aValue;
25(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end;
26(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
27(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
28(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    gc1 := TGenericsClass1<Integer>.Create(10);
29(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Writeln(gc1.Value);
30(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    FreeAndNil(gc1);
31(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
32(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Readln;
33(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end.

 

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

 九、体验泛型约束条件

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

1、类类型约束条件

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

 1(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)program TestGenericClass;
 2(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 3(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二){$APPTYPE CONSOLE}
 4(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 5(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)uses
 6(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    SysUtils;
 7(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 8(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)type
 9(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    TGenericsClass1<T: class> = class  // 注意在此进行约束
10(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    private
11(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        fValue: T;
12(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    public
13(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        constructor Create(aValue: T); virtual;
14(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        property Value: T read fValue write fValue;
15(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    end;
16(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
17(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)var
18(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    gc1: TGenericsClass1<TObject>;
19(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
20(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二){ TGenericsClass1<T> }
21(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
22(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)constructor TGenericsClass1<T>.Create(aValue: T);
23(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
24(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    fValue := aValue;
25(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end;
26(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
27(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
28(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    gc1 := TGenericsClass1<TObject>.Create(nil);
29(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Writeln(gc1.Value = nil);
30(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    FreeAndNil(gc1);
31(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
32(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Readln;
33(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end.

 

 2、对象类型约束条件

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

 

 1(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)program TestGenericArray;
 2(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 3(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二){$APPTYPE CONSOLE}
 4(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 5(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)uses
 6(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    SysUtils,
 7(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Classes,
 8(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Contnrs;
 9(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
10(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)type
11(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    TGenericsClass1<T: TList> = class  // 注意在此进行约束
12(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    private
13(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        fValue: T;
14(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    public
15(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        constructor Create(aValue: T); virtual;
16(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        property Value: T read fValue write fValue;
17(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    end;
18(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
19(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)var
20(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    gc1: TGenericsClass1<TObjectList>;
21(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
22(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二){ TGenericsClass1<T> }
23(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
24(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)constructor TGenericsClass1<T>.Create(aValue: T);
25(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
26(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    fValue := aValue;
27(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end;
28(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
29(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
30(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    gc1 := TGenericsClass1<TObjectList>.Create(nil);
31(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Writeln(gc1.Value = nil);
32(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    FreeAndNil(gc1);
33(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
34(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Readln;
35(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end.

 

 3、构造函数约束条件

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

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

 

1(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)TGeneric<T: constructor> = class
2(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)public
3(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    constructor Create; virtual;
4(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end;

 

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

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

 

1(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)var
2(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    t: T;
3(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
4(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    t := T.Create;
5(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end;

 

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

 4、值类型约束条件

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

 5、多约束条件

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

 

 1(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)program TestGenericArray;
 2(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 3(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二){$APPTYPE CONSOLE}
 4(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
 5(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)uses
 6(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    SysUtils,
 7(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Classes,
 8(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Windows,
 9(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Contnrs;
10(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
11(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)type
12(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    IInt = Interface
13(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        procedure Test;
14(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    End;
15(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
16(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    TImp = class(TInterfacedObject, IInt)
17(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    public
18(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        procedure Test;
19(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    end;
20(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
21(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    TGenericsClass<T: class, IInt> = class  // 注意在此进行约束
22(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    private
23(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        fValue: T;
24(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    public
25(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        constructor Create(aValue: T); virtual;
26(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)        property Value: T read fValue write fValue;
27(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    end;
28(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
29(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)var
30(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    gc1: TGenericsClass<TImp>;
31(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
32(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二){ TGenericsClass<T> }
33(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
34(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)constructor TGenericsClass<T>.Create(aValue: T);
35(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
36(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    fValue := aValue;
37(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end;
38(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
39(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二){ TImp }
40(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
41(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)procedure TImp.Test;
42(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
43(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
44(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end;
45(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
46(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)begin
47(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    gc1 := TGenericsClass<TImp>.Create(nil);
48(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Writeln(gc1.Value = nil);
49(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    FreeAndNil(gc1);
50(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
51(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    Readln;
52(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)end.

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

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

1(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)type
2(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    TGenericsClass<T: class; T1: TList> = class  // 注意在此进行约束,用“;”将两个模板类型分开进行分别约束
3(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    private
4(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    end;

 7、嵌套约束条件

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

 

1(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)TFelix<T> = class
2(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    public
3(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
4(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    end;
5(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)
6(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    TGenericsClass<T: class; T1: TFelix<T>> = class  // 注意在此进行约束,用“;”将两个模板类型分开进行分别约束
7(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    private
8(原创)Delphi2009初体验 - 语言篇 - 体验泛型(二)    end;

 十、关于特化和偏特化

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

 十一、总结

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

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

 

 

相关文章: