快速导航
六、 体验泛型数组
    七、
    
      体验泛型方法
    
    
  
    八、
    
      体验自定义泛型类 
    
    
  
九、 体验泛型约束条件
1、 类类型约束条件
2、 对象类型约束条件
3、 构造函数约束条件
4、 值类型约束条件
5、 多约束条件
6、 多模板类型分别约束条件7、 嵌套约束条件
十、 关于特化与偏特化
    十一、 
    
      总结
    
    
  
    
      由于正式版还没有发出,官方的帮助文档也没有泄露,所以我没有办法验证
    
    Delphi
    
      对泛型的支持到何种程度了。大家对泛型都很熟悉,具体细节我就不多说了。下面将贴出一些代码,用来验证
    
    Delphi
    
      对泛型的支持并验证是否通过。
    
    
  
六、体验泛型数组
 program
    
    
      TestGenericArray;
    
      program
    
    
      TestGenericArray;
      2
 
      3
 {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      4
 
      5
 uses
    
    
      uses
    
    
      6
 SysUtils;
      SysUtils;
      7
 
      8
 type
    
    
      type
    
    
      9
 TArr
    
    
      <
    
    
      T
    
    
      >
    
    
    
    
      =
    
    
    
    
      array
    
    
    
    
      of
    
    
      T;
      TArr
    
    
      <
    
    
      T
    
    
      >
    
    
    
    
      =
    
    
    
    
      array
    
    
    
    
      of
    
    
      T;
      10
 
      11
 var
    
    
      var
    
    
      12
 arr:TArr
    
    
      <
    
    
      Integer
    
    
      >
    
    
      ;
      arr:TArr
    
    
      <
    
    
      Integer
    
    
      >
    
    
      ;
      13
 n:Integer;
      n:Integer;
      14
 begin
    
    
      begin
    
    
      15
 Setlength(arr,
    
    
      10
    
    
      );
      Setlength(arr,
    
    
      10
    
    
      );
      16
 
      17
 for
    
    
      n:
    
    
      =
    
    
    
    
      0
    
    
    
    
      to
    
    
    
    
      9
    
    
    
    
      do
    
    
      for
    
    
      n:
    
    
      =
    
    
    
    
      0
    
    
    
    
      to
    
    
    
    
      9
    
    
    
    
      do
    
    
      18
 begin
    
    
      begin
    
    
      19
 arr[n]:
    
    
      =
    
    
      n;
      arr[n]:
    
    
      =
    
    
      n;
      20
 end
    
    
      ;
    
    
      end
    
    
      ;
      21
 end
    
    
      .
    
    
      end
    
    
      .
      22
 
    
  七、体验泛型方法
    1、Delphi2009不支持全局泛型方法,泛型方法只能置于类内或者嵌套在方法内,或者成为类的静态方法。
    
     2、以下代码将打印出传入泛型变量的地址:
    
  
 program
    
    
      TestGenericArray;
    
      program
    
    
      TestGenericArray;
      2
 
      3
 {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      4
 
      5
 uses
    
    
      uses
    
    
      6
 SysUtils;
      SysUtils;
      7
 
      8
 type
    
    
      type
    
    
      9
 TGeneric
    
    
      =
    
    
    
    
      class
      TGeneric
    
    
      =
    
    
    
    
      class
    
    
      10
 class
    
    
    
    
      procedure
    
    
      PrintAddress
    
    
      <
    
    
      T
    
    
      >
    
    
      (aVal:T);
    
    
      class
    
    
    
    
      procedure
    
    
      PrintAddress
    
    
      <
    
    
      T
    
    
      >
    
    
      (aVal:T);
      11
 end
    
    
      ;
    
    
      end
    
    
      ;
      12
 
      13
 var
    
    
      var
    
    
      14
 n:Integer;
      n:Integer;
      15
 
      16
 {
    
    
      TGeneric
    
    
      }
    
    
      {
    
    
      TGeneric
    
    
      }
    
    
      17
 
      18
 class
    
    
    
    
      procedure
    
    
      TGeneric.PrintAddress
    
    
      <
    
    
      T
    
    
      >
    
    
      (aVal:T);
    
    
      class
    
    
    
    
      procedure
    
    
      TGeneric.PrintAddress
    
    
      <
    
    
      T
    
    
      >
    
    
      (aVal:T);
      19
 begin
    
    
      begin
    
    
      20
 Writeln(Integer(@aVal));
      Writeln(Integer(@aVal));
      21
 end
    
    
      ;
    
    
      end
    
    
      ;
      22
 
      23
 begin
    
    
      begin
    
    
      24
 n:
    
    
      =
    
    
    
    
      10
    
    
      ;
      n:
    
    
      =
    
    
    
    
      10
    
    
      ;
      25
 TGeneric.PrintAddress
    
    
      <
    
    
      Integer
    
    
      >
    
    
      (n);
      TGeneric.PrintAddress
    
    
      <
    
    
      Integer
    
    
      >
    
    
      (n);
      26
 end
    
    
      .
    
    
      end
    
    
      .
      
八、体验自定义泛型类
 program
    
    
      TestGenericClass;
    
      program
    
    
      TestGenericClass;
      2
 
      3
 {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      4
 
      5
 uses
    
    
      uses
    
    
      6
 SysUtils;
      SysUtils;
      7
 
      8
 type
    
    
      type
    
    
      9
 TGenericsClass1
    
    
      <
    
    
      T
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
      TGenericsClass1
    
    
      <
    
    
      T
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
      10
 private
    
    
      private
    
    
      11
 fValue:T;
      fValue:T;
      12
 public
    
    
      public
    
    
      13
 constructor
    
    
      Create(aValue:T);
    
    
      virtual
    
    
      ;
    
    
      constructor
    
    
      Create(aValue:T);
    
    
      virtual
    
    
      ;
      14
 property
    
    
      Value:T
    
    
      read
    
    
      fValue
    
    
      write
    
    
      fValue;
    
    
      property
    
    
      Value:T
    
    
      read
    
    
      fValue
    
    
      write
    
    
      fValue;
      15
 end
    
    
      ;
    
    
      end
    
    
      ;
      16
 
      17
 var
    
    
      var
    
    
      18
 gc1:TGenericsClass1
    
    
      <
    
    
      Integer
    
    
      >
    
    
      ;
      gc1:TGenericsClass1
    
    
      <
    
    
      Integer
    
    
      >
    
    
      ;
      19
 
      20
 {
    
    
      TGenericsClass1<T>
    
    
      }
    
    
      {
    
    
      TGenericsClass1<T>
    
    
      }
    
    
      21
 
      22
 constructor
    
    
      TGenericsClass1
    
    
      <
    
    
      T
    
    
      >
    
    
      .Create(aValue:T);
    
    
      constructor
    
    
      TGenericsClass1
    
    
      <
    
    
      T
    
    
      >
    
    
      .Create(aValue:T);
      23
 begin
    
    
      begin
    
    
      24
 fValue:
    
    
      =
    
    
      aValue;
      fValue:
    
    
      =
    
    
      aValue;
      25
 end
    
    
      ;
    
    
      end
    
    
      ;
      26
 
      27
 begin
    
    
      begin
    
    
      28
 gc1:
    
    
      =
    
    
      TGenericsClass1
    
    
      <
    
    
      Integer
    
    
      >
    
    
      .Create(
    
    
      10
    
    
      );
      gc1:
    
    
      =
    
    
      TGenericsClass1
    
    
      <
    
    
      Integer
    
    
      >
    
    
      .Create(
    
    
      10
    
    
      );
      29
 Writeln(gc1.Value);
      Writeln(gc1.Value);
      30
 FreeAndNil(gc1);
      FreeAndNil(gc1);
      31
 
      32
 Readln;
      Readln;
      33
 end
    
    
      .
    
    
      end
    
    
      .
      
九、体验泛型约束条件
以下通过代码针对泛型类,对Delphi2009所支持的泛型约束条件进行验证。
1、类类型约束条件
约束模板类型T只能为类类型
 program
    
    
      TestGenericClass;
    
      program
    
    
      TestGenericClass;
      2
 
      3
 {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      4
 
      5
 uses
    
    
      uses
    
    
      6
 SysUtils;
      SysUtils;
      7
 
      8
 type
    
    
      type
    
    
      9
 TGenericsClass1
    
    
      <
    
    
      T:
    
    
      class
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束
      TGenericsClass1
    
    
      <
    
    
      T:
    
    
      class
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束
      10
 private
    
    
      private
    
    
      11
 fValue:T;
      fValue:T;
      12
 public
    
    
      public
    
    
      13
 constructor
    
    
      Create(aValue:T);
    
    
      virtual
    
    
      ;
    
    
      constructor
    
    
      Create(aValue:T);
    
    
      virtual
    
    
      ;
      14
 property
    
    
      Value:T
    
    
      read
    
    
      fValue
    
    
      write
    
    
      fValue;
    
    
      property
    
    
      Value:T
    
    
      read
    
    
      fValue
    
    
      write
    
    
      fValue;
      15
 end
    
    
      ;
    
    
      end
    
    
      ;
      16
 
      17
 var
    
    
      var
    
    
      18
 gc1:TGenericsClass1
    
    
      <
    
    
      TObject
    
    
      >
    
    
      ;
      gc1:TGenericsClass1
    
    
      <
    
    
      TObject
    
    
      >
    
    
      ;
      19
 
      20
 {
    
    
      TGenericsClass1<T>
    
    
      }
    
    
      {
    
    
      TGenericsClass1<T>
    
    
      }
    
    
      21
 
      22
 constructor
    
    
      TGenericsClass1
    
    
      <
    
    
      T
    
    
      >
    
    
      .Create(aValue:T);
    
    
      constructor
    
    
      TGenericsClass1
    
    
      <
    
    
      T
    
    
      >
    
    
      .Create(aValue:T);
      23
 begin
    
    
      begin
    
    
      24
 fValue:
    
    
      =
    
    
      aValue;
      fValue:
    
    
      =
    
    
      aValue;
      25
 end
    
    
      ;
    
    
      end
    
    
      ;
      26
 
      27
 begin
    
    
      begin
    
    
      28
 gc1:
    
    
      =
    
    
      TGenericsClass1
    
    
      <
    
    
      TObject
    
    
      >
    
    
      .Create(
    
    
      nil
    
    
      );
      gc1:
    
    
      =
    
    
      TGenericsClass1
    
    
      <
    
    
      TObject
    
    
      >
    
    
      .Create(
    
    
      nil
    
    
      );
      29
 Writeln(gc1.Value
    
    
      =
    
    
    
    
      nil
    
    
      );
      Writeln(gc1.Value
    
    
      =
    
    
    
    
      nil
    
    
      );
      30
 FreeAndNil(gc1);
      FreeAndNil(gc1);
      31
 
      32
 Readln;
      Readln;
      33
 end
    
    
      .
    
    
      end
    
    
      .
    
  
2、对象类型约束条件
约束T只能为某一个对象类型
 program
    
    
      TestGenericArray;
    
      program
    
    
      TestGenericArray;
      2
 
      3
 {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      4
 
      5
 uses
    
    
      uses
    
    
      6
 SysUtils,
      SysUtils,
      7
 Classes,
      Classes,
      8
 Contnrs;
      Contnrs;
      9
 
      10
 type
    
    
      type
    
    
      11
 TGenericsClass1
    
    
      <
    
    
      T:TList
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束
      TGenericsClass1
    
    
      <
    
    
      T:TList
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束
      12
 private
    
    
      private
    
    
      13
 fValue:T;
      fValue:T;
      14
 public
    
    
      public
    
    
      15
 constructor
    
    
      Create(aValue:T);
    
    
      virtual
    
    
      ;
    
    
      constructor
    
    
      Create(aValue:T);
    
    
      virtual
    
    
      ;
      16
 property
    
    
      Value:T
    
    
      read
    
    
      fValue
    
    
      write
    
    
      fValue;
    
    
      property
    
    
      Value:T
    
    
      read
    
    
      fValue
    
    
      write
    
    
      fValue;
      17
 end
    
    
      ;
    
    
      end
    
    
      ;
      18
 
      19
 var
    
    
      var
    
    
      20
 gc1:TGenericsClass1
    
    
      <
    
    
      TObjectList
    
    
      >
    
    
      ;
      gc1:TGenericsClass1
    
    
      <
    
    
      TObjectList
    
    
      >
    
    
      ;
      21
 
      22
 {
    
    
      TGenericsClass1<T>
    
    
      }
    
    
      {
    
    
      TGenericsClass1<T>
    
    
      }
    
    
      23
 
      24
 constructor
    
    
      TGenericsClass1
    
    
      <
    
    
      T
    
    
      >
    
    
      .Create(aValue:T);
    
    
      constructor
    
    
      TGenericsClass1
    
    
      <
    
    
      T
    
    
      >
    
    
      .Create(aValue:T);
      25
 begin
    
    
      begin
    
    
      26
 fValue:
    
    
      =
    
    
      aValue;
      fValue:
    
    
      =
    
    
      aValue;
      27
 end
    
    
      ;
    
    
      end
    
    
      ;
      28
 
      29
 begin
    
    
      begin
    
    
      30
 gc1:
    
    
      =
    
    
      TGenericsClass1
    
    
      <
    
    
      TObjectList
    
    
      >
    
    
      .Create(
    
    
      nil
    
    
      );
      gc1:
    
    
      =
    
    
      TGenericsClass1
    
    
      <
    
    
      TObjectList
    
    
      >
    
    
      .Create(
    
    
      nil
    
    
      );
      31
 Writeln(gc1.Value
    
    
      =
    
    
    
    
      nil
    
    
      );
      Writeln(gc1.Value
    
    
      =
    
    
    
    
      nil
    
    
      );
      32
 FreeAndNil(gc1);
      FreeAndNil(gc1);
      33
 
      34
 Readln;
      Readln;
      35
 end
    
    
      .
    
    
      end
    
    
      .
    
  
3、构造函数约束条件
大家都知道,在C#中,可以使用 T: where new() 对泛型模板类型进行构造函数的约束,指明 类型T 必须有一个可见的构造函数。
在D2009中,我也发现有这样的特性:
 TGeneric
    
    
      <
    
    
      T:
    
    
      constructor
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
      TGeneric
    
    
      <
    
    
      T:
    
    
      constructor
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
      2
 public
    
    
      public
    
    
      3
 constructor
    
    
      Create;
    
    
      virtual
    
    
      ;
    
    
      constructor
    
    
      Create;
    
    
      virtual
    
    
      ;
      4
 end
    
    
      ;
    
    
      end
    
    
      ;
    
  
约束“: constructor”表明T必须拥有可见的构造函数。
但是,我在使用以下代码时,编译器总是提示编译不通过:
 var
    
      var
    
    
      2
 t:T;
      t:T;
      3
 begin
    
    
      begin
    
    
      4
 t:
    
    
      =
    
    
      T.Create;
      t:
    
    
      =
    
    
      T.Create;
      5
 end
    
    
      ;
    
    
      end
    
    
      ;
    
  
获取是另外一种写法?我没有尝试出来,需要等官方正式版出来才能确认。
4、值类型约束条件
    Delphi2009的泛型约束不提供值类型约束条件,TGenericsClass1<T: Integer> = class这样的约束编译器是不支持的。所以,像c++中template <Tint S> class TBuf这样的约束在Delphi中行不通。
    
  
5、多约束条件
    与C#类似,Delphi2009的多约束条件用来约束T既满足一个类型,又满足一个接口。
    
  
 program
    
    
      TestGenericArray;
    
      program
    
    
      TestGenericArray;
      2
 
      3
 {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      {
    
    
      $APPTYPECONSOLE
    
    
      }
    
    
      4
 
      5
 uses
    
    
      uses
    
    
      6
 SysUtils,
      SysUtils,
      7
 Classes,
      Classes,
      8
 Windows,
      Windows,
      9
 Contnrs;
      Contnrs;
      10
 
      11
 type
    
    
      type
    
    
      12
 IInt
    
    
      =
    
    
      Interface
      IInt
    
    
      =
    
    
      Interface
      13
 procedure
    
    
      Test;
    
    
      procedure
    
    
      Test;
      14
 End;
      End;
      15
 
      16
 TImp
    
    
      =
    
    
    
    
      class
    
    
      (TInterfacedObject,IInt)
      TImp
    
    
      =
    
    
    
    
      class
    
    
      (TInterfacedObject,IInt)
      17
 public
    
    
      public
    
    
      18
 procedure
    
    
      Test;
    
    
      procedure
    
    
      Test;
      19
 end
    
    
      ;
    
    
      end
    
    
      ;
      20
 
      21
 TGenericsClass
    
    
      <
    
    
      T:
    
    
      class
    
    
      ,IInt
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束
      TGenericsClass
    
    
      <
    
    
      T:
    
    
      class
    
    
      ,IInt
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束
      22
 private
    
    
      private
    
    
      23
 fValue:T;
      fValue:T;
      24
 public
    
    
      public
    
    
      25
 constructor
    
    
      Create(aValue:T);
    
    
      virtual
    
    
      ;
    
    
      constructor
    
    
      Create(aValue:T);
    
    
      virtual
    
    
      ;
      26
 property
    
    
      Value:T
    
    
      read
    
    
      fValue
    
    
      write
    
    
      fValue;
    
    
      property
    
    
      Value:T
    
    
      read
    
    
      fValue
    
    
      write
    
    
      fValue;
      27
 end
    
    
      ;
    
    
      end
    
    
      ;
      28
 
      29
 var
    
    
      var
    
    
      30
 gc1:TGenericsClass
    
    
      <
    
    
      TImp
    
    
      >
    
    
      ;
      gc1:TGenericsClass
    
    
      <
    
    
      TImp
    
    
      >
    
    
      ;
      31
 
      32
 {
    
    
      TGenericsClass<T>
    
    
      }
    
    
      {
    
    
      TGenericsClass<T>
    
    
      }
    
    
      33
 
      34
 constructor
    
    
      TGenericsClass
    
    
      <
    
    
      T
    
    
      >
    
    
      .Create(aValue:T);
    
    
      constructor
    
    
      TGenericsClass
    
    
      <
    
    
      T
    
    
      >
    
    
      .Create(aValue:T);
      35
 begin
    
    
      begin
    
    
      36
 fValue:
    
    
      =
    
    
      aValue;
      fValue:
    
    
      =
    
    
      aValue;
      37
 end
    
    
      ;
    
    
      end
    
    
      ;
      38
 
      39
 {
    
    
      TImp
    
    
      }
    
    
      {
    
    
      TImp
    
    
      }
    
    
      40
 
      41
 procedure
    
    
      TImp.Test;
    
    
      procedure
    
    
      TImp.Test;
      42
 begin
    
    
      begin
    
    
      43
 
      44
 end
    
    
      ;
    
    
      end
    
    
      ;
      45
 
      46
 begin
    
    
      begin
    
    
      47
 gc1:
    
    
      =
    
    
      TGenericsClass
    
    
      <
    
    
      TImp
    
    
      >
    
    
      .Create(
    
    
      nil
    
    
      );
      gc1:
    
    
      =
    
    
      TGenericsClass
    
    
      <
    
    
      TImp
    
    
      >
    
    
      .Create(
    
    
      nil
    
    
      );
      48
 Writeln(gc1.Value
    
    
      =
    
    
    
    
      nil
    
    
      );
      Writeln(gc1.Value
    
    
      =
    
    
    
    
      nil
    
    
      );
      49
 FreeAndNil(gc1);
      FreeAndNil(gc1);
      50
 
      51
 Readln;
      Readln;
      52
 end
    
    
      .
    
    
      end
    
    
      .
    
  6、多模板类型分别约束条件
    有两个模板类型T1、T2,要使用不同的约束分别约束两个模板类型,可以使用以下方法:
    
    
  
 type
    
      type
    
    
      2
 TGenericsClass
    
    
      <
    
    
      T:
    
    
      class
    
    
      ;T1:TList
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束,用“;”将两个模板类型分开进行分别约束
      TGenericsClass
    
    
      <
    
    
      T:
    
    
      class
    
    
      ;T1:TList
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束,用“;”将两个模板类型分开进行分别约束
      3
 private
    
    
      private
    
    
      4
 end
    
    
      ;
    
    
      end
    
    
      ;
    
  7、嵌套约束条件
    Delphi2009的泛型约束条件对嵌套约束条件处理的很好,如:
    
  
 TFelix
    
    
      <
    
    
      T
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
      TFelix
    
    
      <
    
    
      T
    
    
      >
    
    
    
    
      =
    
    
    
    
      class
    
    
      2
 public
    
    
      public
    
    
      3
 
      4
 end
    
    
      ;
    
    
      end
    
    
      ;
      5
 
      6
 TGenericsClass
    
    
      <
    
    
      T:
    
    
      class
    
    
      ;T1:TFelix
    
    
      <
    
    
      T
    
    
      >>
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束,用“;”将两个模板类型分开进行分别约束
      TGenericsClass
    
    
      <
    
    
      T:
    
    
      class
    
    
      ;T1:TFelix
    
    
      <
    
    
      T
    
    
      >>
    
    
    
    
      =
    
    
    
    
      class
    
    
    
    
      //
    
    
      注意在此进行约束,用“;”将两个模板类型分开进行分别约束
      7
 private
    
    
      private
    
    
      8
 end
    
    
      ;
    
    
      end
    
    
      ;
    
  十、关于特化和偏特化
谢谢网友“ 装配脑袋” 的提醒,我试了很多方法,都没有迹象表明D2009支持C++中模板的特化和偏特化,或者D2009用其他形式的语法表示特化与偏特化,导致我没有试验出来。
十一、总结
总体上来说,D2009从泛型的角度出发,做得已经非常不错了,已经非常接近C#。甚至,D2009还提供类似于C#的关键字“default”,来获取泛型类型T的默认值(值类型置0,引用类型为空指针)。
在接下来的章节里,我会向大家介绍D2009的其他新体验,如:匿名函数和反射(比RTTI更强大)的支持。


 
     
     
					 
					