用过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来描述,除了知道是一个值类型之外,连成员函数都不知道。
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来描述,除了知道是一个值类型之外,连成员函数都不知道。
//你是冲着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.
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.//自己建立窗口测试, 或使用部分代码测试即可