C++中的模板、C#等语言中泛型技术,给许多操作不同类型数据的软件人员提供了一个很好的方法。其类型的“可变”性,让许多用过的软件人员所心喜。但是在Delphi 2009以前的版本中,是从来没有的。让许多不会用Delphi中TList的人员,大大的抱怨。如果用好Delphi中TList,其可用性,我个人认为,比其它语言中的泛型好用很多(当然对指针的应用和内存的分配、释放不了解的人除外)。
????? 自从Delphi 2009的发布,给许多喜欢用泛型技术的软件人员,提供了方便。由于Delphi 2009不太稳定,也没有过多的去用其泛型技术。Delphi 2010发布以来,出现许多“Delphi 2010初体验,是时候抛弃Delphi 7了”的话语的满天飞,让我想一看其究竟。
???? 闲话少说,Delphi 2010的泛型单元Generics.Defaults、Generics.Collections;重点还是Generics.Collections单元,其中有TArray泛型类、TList<T>(列表的泛型)、TQueue<T>(队列的泛型)、TStack<T> (栈的泛型)、TDictionary<TKey,TValue> (Hash Table哈希表的泛型)及其上述泛型所对应的TObject的泛型,非常广泛。
?
简单的泛型类应用:(转)
-----------------------------------------------------------------------------------------------
unit Unit1;
interface
uses
? Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
? Dialogs,StdCtrls;
type
? TForm1 = class(TForm)
??? Memo1: TMemo;
??? Edit1: TEdit;
??? Edit2: TEdit;
??? Button1: TButton;
??? Button2: TButton;
??? Button3: TButton;
??? Button4: TButton;
??? procedure FormCreate(Sender: TObject);
??? procedure FormDestroy(Sender: TObject);
??? procedure Button1Click(Sender: TObject);
??? procedure Button2Click(Sender: TObject);
??? procedure Button3Click(Sender: TObject);
??? procedure Button4Click(Sender: TObject);
? end;
var
? Form1: TForm1;
implementation
{$R *.dfm}
uses Generics.Collections; {Delphi? 泛型容器单元}
var
? Dictionary: TDictionary<Cardinal,string>;??
? {定义一个泛型 TDictionary 类,指定有 Cardinal、string 构成}
{建立}
procedure TForm1.FormCreate(Sender: TObject);
begin
? Dictionary := TDictionary<Cardinal,string>.Create;
? Memo1.Clear;
? Button1.Caption := Button1.Caption + ' 添加';
? Button2.Caption := Button2.Caption + ' 删除';
? Button3.Caption := Button3.Caption + ' 尝试取值';
? Button4.Caption := Button4.Caption + ' 清空';
? Edit1.Clear;
? Edit2.Clear;
? Edit1.NumbersOnly := True;
end;
{释放}
procedure TForm1.FormDestroy(Sender: TObject);
begin
? Dictionary.Free;
end;
{添加}
procedure TForm1.Button1Click(Sender: TObject);
var
? key: Cardinal;
? value: string;
? str: string;
? k,v: Boolean;
begin
? key := StrToIntDef(Edit1.Text,0);
? value := Edit2.Text;
? if value = '' then value := 'Null';
? k := Dictionary.ContainsKey(key);???? {Key 是否存在}
? v := Dictionary.ContainsValue(value); {Value 是否存在}
??
? if not k then
? begin
??? Dictionary.Add(key,value);
??? Memo1.Lines.Add(Format('%d=%s',[key,value])); {同步显示}
? end;
? if k and not v then
? begin
??? str := Format('key 已存在: %d=%s; 是否修改其值?',Dictionary[key]]);
??? if MessageBox(0,PChar(str),'提示',MB_OKCANCEL or MB_ICONQUESTION) = mrOk then
??? begin
????? //Dictionary[key] := value; {Dictionary[key] = Dictionary.Item[key]}
????? Dictionary.AddOrSetValue(key,value);?????? {也可使用上一句}
????? Memo1.Lines.Values[IntToStr(key)] := value; {同步显示}
??? end;
? end;
? if k and v then
? begin
??? str := Format('%d=%s 已存在,不能重复添加',value]);
??? MessageBox(0,'错误',MB_OK + MB_ICONHAND);
? end;
? Text := IntToStr(Dictionary.Count);
end;
{删除: Remove}
procedure TForm1.Button2Click(Sender: TObject);
var
? key: Integer;
? i: Integer;
begin
? key := StrToIntDef(Edit1.Text,0);
? if not Dictionary.ContainsKey(key) then??
? begin
??? ShowMessageFmt('key: %d 不存在',[key]);
??? Exit;
? end;
????
? Dictionary.Remove(key);
? Text := IntToStr(Dictionary.Count);
??
? {同步显示}
? i := Memo1.Lines.IndexOfName(IntToStr(key));
? if i > -1 then Memo1.Lines.Delete(i);
end;
{尝试取值: TryGetValue}
procedure TForm1.Button3Click(Sender: TObject);
var
? key: Integer;
? value: string;
begin
? key := StrToIntDef(Edit1.Text,0);
? if Dictionary.TryGetValue(key,value) then
??? ShowMessageFmt('key: %d 已存在,其值是: %s',value])
? else
??? ShowMessageFmt('key: %d 不存在',[key])
end;
{清空: Clear}
procedure TForm1.Button4Click(Sender: TObject);
begin
? Dictionary.Clear;
? Text := IntToStr(Dictionary.Count);
? Memo1.Clear; {同步显示}
end;
end.
--------------------------------------------------------------------------------
自定义泛型应用:(转)
type
? TForm1 = class(TForm)
??? Memo1: TMemo;
??? Button1: TButton;
??? Button2: TButton;
??? Button3: TButton;
??? Button4: TButton;
??? Button5: TButton;
??? procedure Button1Click(Sender: TObject);
??? procedure Button2Click(Sender: TObject);
??? procedure Button3Click(Sender: TObject);
??? procedure Button4Click(Sender: TObject);
??? procedure Button5Click(Sender: TObject);
? end;
type
? TArr<T> = array[0..9] of T; {定义一个泛型数组}
? {虽然大家习惯用 T 来泛指其他类型,但使用其他合法的标识符也是可以的}
{用作 Integer}
procedure TForm1.Button1Click(Sender: TObject);
var
? Arr: TArr<Integer>;
? i: Integer;
begin
? for i := Low(Arr) to High(Arr) do
??? Arr[i] := i * i;
? Memo1.Clear;
? for i := Low(Arr) to High(Arr) do
??? Memo1.Lines.Add(Format('Arr[%d] = %d',[i,Arr[i]]));
end;
{用作 string}
procedure TForm1.Button2Click(Sender: TObject);
var
? Arr: TArr<string>;
? i: Integer;
begin
? for i := Low(Arr) to High(Arr) do
??? Arr[i] := StringOfChar(Char(i+97),3);
? Memo1.Clear;
? for i := Low(Arr) to High(Arr) do
??? Memo1.Lines.Add(Format('Arr[%d] = %s',51); font-family:Arial; font-size:14px; line-height:26px"> {用作 Single}
procedure TForm1.Button3Click(Sender: TObject);
var
? Arr: TArr<Single>;
? i: Integer;
begin
? for i := Low(Arr) to High(Arr) do
??? Arr[i] := 100 / (i+1);
? Memo1.Clear;
? for i := Low(Arr) to High(Arr) do
??? Memo1.Lines.Add(Format('Arr[%d] = %f',51); font-family:Arial; font-size:14px; line-height:26px"> {用作记录 TPoint}
procedure TForm1.Button4Click(Sender: TObject);
var
? Arr: TArr<TPoint>;
? i: Integer;
begin
? for i := Low(Arr) to High(Arr) do
??? Arr[i] := Point(i,i*2);
? Memo1.Clear;
? for i := Low(Arr) to High(Arr) do
??? Memo1.Lines.Add(Format('Arr[%d] = (%d,%d)',Arr[i].X,Arr[i].Y]));
end;
{用作类 TButton}
procedure TForm1.Button5Click(Sender: TObject);
var
? Arr: TArr<TButton>;
? i: Integer;
begin
? for i := Low(Arr) to High(Arr) do
? begin
??? Arr[i] := TButton.Create(Self);
??? Arr[i].Name := Concat('Btn',IntToStr(i+1));
? end;
? Memo1.Clear;
? for i := Low(Arr) to High(Arr) do
??? Memo1.Lines.Add(Format('Arr[%d] is %s',Arr[i].Name]));
end;
end.