用过C++的模板后,刚接触Delphi的泛型,好不习惯。
TMyClass<T> = class
  FT : T;
  procedure DoIt;
end;//全局函数,全局函数也不支持泛型……
procedure GDoIt(var T : Integer); overload;
procedure GDoIt(var T : Single); overload;procedure TMyClass<T>.DoIt;
begin
  GDoIt(FT); //居然不允许,没有类型推导
end;var
  v : TMyClass<Integer>; ...  v.DoIt;
没有弄明白Delphi中泛型的一些机制,总是套用C++,
这个是典型的类型推导,居然不支持,让我很觉得意外。不过Delphi中的泛型中有约束的概念,要比C++中的明确很多。
由于约束的描述太过复杂,就用了record,class和Interface,
用Interface和class来描述约束,还是很好的,
但是用record来描述,除了知道是一个值类型之外,连成员函数都不知道。

解决方案 »

  1.   


    //你是冲着C++就去了  哈哈
    unit Unit11;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Generics.Collections, StdCtrls;type
      TForm11 = class(TForm)
        btn1: TButton;
        procedure btn1Click(Sender: TObject);
      private
        { Private declarations }
        procedure fun<T>(Value : T);
      public
        { Public declarations }
      end;  TMyClass<T> = class
      private
        FT : T;
      public
        procedure DoIt(Value : T);
      end;var
      Form11: TForm11;implementation
    {$R *.dfm}procedure TForm11.btn1Click(Sender: TObject);
    var
      MyClass1 : TMyClass<string>;
      MyClass2 : TMyClass<integer>;
    begin
      fun<Integer>(123);
      fun<string>('abc');  MyClass1 := TMyClass<string>.Create;
      try
        MyClass1.DoIt('abc');
      finally
        MyClass1.Free;
      end;  MyClass2 := TMyClass<integer>.Create;
      try
        MyClass2.DoIt(123);
      finally
        MyClass2.Free;
      end;
    end;procedure TForm11.fun<T>(Value: T);
    var
      FT : T;
    begin
      FT := Value;
    end;{ TMyClass<T> }procedure TMyClass<T>.DoIt(Value: T);
    begin
      FT := Value;
    end;end.
      

  2.   

    simonhehe,这里的代码其实没有用到类型推导。
      

  3.   


    unit Unit11;
    {
    不需要关注类或方法的命名}interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Generics.Collections, Generics.Defaults, StdCtrls;type
      TForm11 = class(TForm)
        btn1: TButton;
        mmo1: TMemo;
        procedure btn1Click(Sender: TObject);
      private
        { Private declarations }
        function aa<T>: string; overload;
        function aa<T>(Value : T): string; overload;
      public
        { Public declarations }
      end;  {
      泛型对象内部可以直接通过T获取类型信息  TypeInfo(T)
      外部通过Obj.ClassInfo获取PTypeInfo, 是针对对象信息的
      }
      TMyList<T> = class(TList<T>)
      public
        constructor Create;
        procedure msg;
      end;  {泛型申明时用<字符>表示, 不限于T或E}
      TFunClz = class
        function bb<E>(Value : E): string;
        class function bbb<T>(Value : T): string;
      end;//  function bb<e>(Value : e): string;   //全局方法/函数不能使用泛型var
      Form11: TForm11;
      AGlobal : TList<string>;implementation
    uses TypInfo;
    {$R *.dfm}
    {
    function bbb<T>(Value : T): string;  //全局方法/函数不能使用泛型
    beginend;}function TForm11.aa<T>: string;
    var
      info: PTypeInfo;
    begin
      info := TypeInfo(T);
      Result := info.Name + ':' + IntToStr(Ord(info.Kind));
    end;function TForm11.aa<T>(Value: T): string;
    beginend;procedure TForm11.btn1Click(Sender: TObject);
    var
      lst : TMyList<string>;
      lst2 : TMyList<TObject>;
      p : PTypeInfo;
      AObj : TFunClz;
    begin
      mmo1.Clear;  mmo1.Lines.Add('fun a<T>:string--------------');
      mmo1.Lines.Add(aa<string>);
      mmo1.Lines.Add(aa<integer>);
      mmo1.Lines.Add(aa<TList>);
      mmo1.Lines.Add(aa<Tarray<string>>);  mmo1.Lines.Add('');
      mmo1.Lines.Add('TMyList<T> = class(TList<T>)--------------');
      lst := TMyList<string>.Create;
      try
        lst.msg;
        p := lst.ClassInfo;
        mmo1.Lines.Add('ClassInfo=' + p.Name);
      finally
        lst.Free;
      end;  mmo1.Lines.Add('');
      lst2 := TMyList<TObject>.Create;
      try
        lst2.msg;
        p := lst.ClassInfo;
        mmo1.Lines.Add('ClassInfo=' + p.Name);
      finally
        lst2.Free;
      end;  mmo1.Lines.Add('');
      AObj := TFunClz.Create;
      try
        AObj.bb<Double>(12.33);
      finally
        AObj.Free;
      end;  TFunClz.bbb<Tcolor>($FFFFFF);
    end;{ Tlst<T> }constructor TMyList<T>.Create;
    var
      info: PTypeInfo;
    begin
      inherited;
      info := TypeInfo(T);
      Form11.mmo1.Lines.Add('TMyList<T>.Create  ' + info.Name + ':' + IntToStr(Ord(info.Kind)));
    end;procedure TMyList<T>.msg;
    var
      info: PTypeInfo;
    begin
      info := TypeInfo(T);
      Form11.mmo1.Lines.Add('TMyList<T>.msg  ' + info.Name + ':' + IntToStr(Ord(info.Kind)));
    end;{ TFunClz }function TFunClz.bb<E>(Value: E): string;
    var
      info: PTypeInfo;
    begin
      info := TypeInfo(E);
      Form11.mmo1.Lines.Add('TFunClz.bb<E>(Value: E)  ' + info.Name + ':' + IntToStr(Ord(info.Kind)));end;
    class function TFunClz.bbb<T>(Value: T): string;
    var
      info: PTypeInfo;
    begin
      info := TypeInfo(T);
      Form11.mmo1.Lines.Add('TFunClz.bbb<T>(Value: T)  ' + info.Name + ':' + IntToStr(Ord(info.Kind)));
    end;end.//自己建立窗口测试, 或使用部分代码测试即可