程诗

程序可以写的像诗。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Delphi中有趣的字符串下标

Posted on 2012-02-12 13:43  程诗  阅读(1808)  评论(0)    收藏  举报

[源:http://www.cnblogs.com/dumbow/archive/2012/02/12/2347899.html]

由于扩展一个老工程的需要,搜罗了一些多语言控件测试,这个工程是在D7下面开发的,而D7对多语言的支持比较弱,今天这个乱码,明天那个乱码。让开发人员忙的不亦乐乎。目前我找到的多语言控件,要么有这样那样的毛病,要么用起来依赖性比较强,反正是弄了一天也没找着很合适的,要么不能改字体,要么不能探查到很复杂的控件的属性。

索性不如自己按照具体的工程需求先凑合一个吧。于是今天用三个控件组合了一个多语言控件,这个控件做的不是那么干净利索,有的时候还需要少许写程序配合一下,尽管把这些程序封装到了控件的事件中,我看着也不是多满意。虽然也不怎么太通用,但是非常适合我要改的这个项目。

今天想记下来的不是这个。

我的这个多语言控件中,需要保存一些对应的字符串数据,比如一堆控件属性名称要一一对应到一堆属性值。因为需要写到类似ini这种结构的文件里,所以可以看作是两个字符串数组的一一对应。但是一一对应有个问题,就是有大量的冗余数据。当时想,如果可以用一个字符串数组来表示,这个数组能引用字符串下标就好了。开始没当真,因为印象里从来没有那个语言提供这个语法。你可能要问,你做两个TString,引用同样的下标不就完了么?这很简单嘛。这里简单的解释一下,设想这两个TString都是这个控件的属性,而这两个属性是相关的,你没有一个手段来控制或称维护这两个属性,那么用户在使用这个控件的时候,很可能出错,而且错的离谱。你的程序要这样检查,那样检查,相当麻烦,而且,这也脱离了面向对象的基本原则了。那你又说,你做一个结构元素的数组来维持不好么?好吧,这就是问题的关键了,数组的下标只能是数字(或更麻烦的其他有序类型),如果一个你本想很简单就能已记事本编辑的文件里,充斥着Txxx[123]之类的行,看都看迷糊了,也就别编辑了。所以,最好是能把这个东西封装起来,不管你维系的这个数组有多麻烦,但是在使用的时候看起来越简单越好。最直接的方式是写一个函数,作为这个类的一个方法比如function GetValueFromName(AName: string):string这个形式。你看到这里可能想扔鸡蛋了!想说:“我开始学写程序不就是这样的么?!”不过,我可不想负责哦。哈哈哈,转入正题,这很有趣,原来在Delphi中,数组还真的可以使用字符串下标。不过到目前为止我看到这种形式只能出现在一个类的属性里。也就是说,随便定义一个变量是不行滴。

看一段程序:


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    function GetStrSub(Name: string): string;
    procedure SetStrSub(Name: string; const Value: string);
    { Private declarations }
  public
    property StrSub[Name: string]: string read GetStrSub write SetStrSub;
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

function TForm1.GetStrSub(Name: string): string;
begin
  {这里只是个示例,实际你可能要有一个复杂的数据操作}
  if Name = 'One' then Result := 'String One';
  if Name = 'Two' then Result := 'String Two';
end;

procedure TForm1.SetStrSub(Name: string; const Value: string);
begin
  //
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  {看见了么?引用变量StrSub的字符串下标,哈哈哈哈}
  ShowMessage(StrSub['One']);
  ShowMessage(StrSub['Two']);
end;

end.


实际的使用中,Delphi的思想都是将这种复杂的数据类型封装为一个类,然后让这个类成为另一个类的属性,比如我们常见的TFont本身就是个类,而这个类又是很多类的一个属性。如果是动态使用,相对简单。但如果想流化这个属性,在编辑时可以让用户在IDE里编辑时可用,还是要做很多工作才行。在Delphi内部,这种东东,是要从两个类继承下来,一个是TOwnedCollection(早期版本使用TCollection),另一个是TCollectionItem。这些个东西,每次用到的时候都忘,索性就不刻意去记了。