Delphi 2010 中的泛型

2010已发布很长时间了,口碑还不错,准备用它开发下一项目,但对泛型等新东西的认识还不够,就搜了一下,发现下面这篇文章,还不错,大家一起补补课吧!

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; 是否修改其值?', [key, 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 已存在, 不能重复添加', [key, value]);
    MessageBox(0, PChar(str), '错误', 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', [key, value])
else
    ShowMessageFmt('key: %d 不存在', [key])
end;

{清空: Clear}
procedure TForm1.Button4Click(Sender: TObject);
begin
Dictionary.Clear;
Text := IntToStr(Dictionary.Count);
Memo1.Clear; {同步显示}
end;

end.

--------------------------------------------------------------------------------

自定义泛型应用:(转)

--------------------------------------------------------------------------------

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

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;

var
Form1: TForm1;

implementation

{$R *.dfm}

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', [i, Arr[i]]));
end;

{用作 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', [i, Arr[i]]));
end;

{用作记录 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)', [i, 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', [i, Arr[i].Name]));
end;

end.

Delphi 2010 中的泛型的更多相关文章

  1. Delphi 2010初体验,是时候抛弃Delphi 7了

    Delphi 2010已于近日由Embarcadero公司发布.作者Kim Madsen作为一名资深的Delphi开发者,在他的博客中谈到了Delphi 2010的新性能.它的使用感受以及对Delph ...

  2. Delphi 2010 安装及调试

    呵呵,毫不客气地说,Delphi 2010 这个版本可以算是 Delphi 的一个“里程碑”,为什么这么说?因为这个版本实现了几个 Delphi 应该有却一直没有的功能 Delphi 2010 的新功 ...

  3. Delphi 2010

    Delphi 2010已早由Embarcadero公司发布.作者Kim Madsen作为一名资深的Delphi开发者,在他的博客中谈到了Delphi 2010的新性能.它的使用感受以及对Delphi语 ...

  4. delphi 2010 动态链接库DLL断点调试

    DELPHI 2010 动态链接库DLL断点调试 马根峰 (广东联合电子服务股份有限公司,广州 510300) 摘要:本文详细介绍了Delphi 2010中的动态链接库DLL断点调试技术 关键词:DE ...

  5. Delphi 2010下使用sqlitesimpledelphi连接SQLite数据库及中文乱码问题的解决

    应女朋友的要求,要写一款销售管理的软件.用于管理服装店每天的销售记录,已及管理服装店的客户,并对客户进行生日提醒 因为之前使用C#写过一款家庭管理软件,主要是自己用,所以使用了服务器型数据库MySQL ...

  6. [转]:Delphi XE中泛型数组的使用范例

    Delphi XE中泛型数组的使用范例,下面的范例简单的使用了泛型字符串数组,如用 TArray 代替 array of Word, 还可以使用 TArray 类提供的算法(就是少了点). uses ...

  7. Delphi 2010 XE 中使用 JSON 之 SuperObject68-6

    JSON之SuperObject(1):一直盼着Delphi能够直接支持"正则:Delphi2009刚来的时候,有了JSON,但:Delphi2010带了两个相关单元:DBXJS:我想不等了 ...

  8. Delphi 2010下载+完美破解

    点击链接进入http://altd.embarcadero.com/download/RADStudio2010/delphicbuilder_2010_3615_win.isoRAD Studio/ ...

  9. Delphi XE5中的新增内容

    Delphi XE5中的新增内容 Delphi XE5是所有Delphi开发人员的必须备升级,并且是来自Embarcadero的获奖的.多设备应用开发解决方案的最新版本.使用Delphi XE5的新特 ...

随机推荐

  1. java中设置http响应头控制浏览器禁止缓存当前文档内容

    response.setDateHeader("expries", -1); response.setHeader("Cache-Control", " ...

  2. php开发面试题---php高级程序员需要掌握的一些知识

    php开发面试题---php高级程序员需要掌握的一些知识 一.总结 一句话总结: 还是需要多多接触架构师的知识,比如这里说的微服务,还有需要php服务端的知识来解决web端的不足,比如Swoole 1 ...

  3. 剑指offer——62数组种数字出现的次数

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 题解: 我们想到异或运算的一个性质:任何一个数字异或它自己都等于0.也就是说,如果我们从头到尾依 ...

  4. MySQL慢查询日志分割

    mysql> set global slow_query_log=0; Query OK, 0 rows affected (0.00 sec)   mysql> set global s ...

  5. ASP.Net 第一天笔记 MVC 控制器与视图数据传递注意事项

    1.如果方法的参数的名称与表单元素Name属性的值一致的话,会自动填充 2.如果表单元素的Name属性与实体类型中属性一致,那么表单中的数据会自动赋值给实体中的属性 3.控制器中重载的方法 方法前上边 ...

  6. LNMP之PHP

    PHP LNMP环境下的PHP安装 CGI指的是通用网关接口,为HTTP服务器与其他机器上的程序服务通信交流的一种工具,性能差,所以被淘汰了. FastCGI,是一个可以伸缩.高速的在HTTP服务器和 ...

  7. python中常见的内置函数

    map #自定义map函数 def map_test(func, list): res = [] for item in list: res.append(func(item)) return res ...

  8. 召回率、AUC、ROC模型评估指标精要

    混淆矩阵 精准率/查准率,presicion 预测为正的样本中实际为正的概率 召回率/查全率,recall 实际为正的样本中被预测为正的概率 TPR F1分数,同时考虑查准率和查全率,二者达到平衡,= ...

  9. 1.MySQL基础架构

    好久没发博客了,终于又学完了一点知识并且进行了整理.就从这个MySQL系列开始继续坚持每个月产出几篇. 声明一下,这次的MySQL系列是针对已有一定基础的小伙伴的,关于SQL的使用,一些概念的介绍就不 ...

  10. chkconfig 与 systemctl

    chkconfig命令 主要用来更新(启动或停止)和查询系统服务(service)的运行级信息,用于维护/etc/rc[0-6].d目录的命令行工具. chkconfig -–add httpd 增加 ...