为什么变量被声明为TStrings并创建为TStringList?

时间:2012-02-21 14:51:30

标签: delphi tstringlist

为什么变量被声明为TStrings并创建为TStringList

例如:var sl声明为TStrings,但创建为TStringList

var
  sl : TStrings;
begin
  sl := TStringList.Create;

  // add string values...
  sl.Add( 'Delphi' );
  sl.Add( '2.01' );

  // get string value using its index
  // sl.Strings( 0 ) will return
  //   'Delphi'
  MessageDlg(
    sl.Strings[ 0 ],
    mtInformation, [mbOk], 0 );

  sl.Free;
end;

4 个答案:

答案 0 :(得分:33)

TStrings是一种抽象类型,没有实现所有方法。

TStringListTStrings的后代并实现所有功能。在您的代码中,您可以将变量声明为TStringList

但是,例如在函数定义中,接受TStrings参数而不是TStringList

是有意义的
procedure doSomething(lst: TStrings);

这使该功能可以使用TStrings的所有实现,而不仅仅是TStringList

答案 1 :(得分:29)

在我看来,这是毫无意义的,尽管完全无害。您可以很好地声明slTStringList,我会一直这样做。对于代码的读者,它使局部变量列表更容易理解。

在此代码中sl总是被分配一个TStringList实例,因此声明sl具有基类类型TStrings无法获得任何结果。但是,如果您的代码为变量分配了各种不同类型的TStrings后代,则将其声明为TStrings是有意义的。

当您可能将变量声明为TStrings类型时,通常是代码未明确创建实例的情况。例如,如果接收到TStrings,那么接收字符串列表作为参数的实用程序方法会更有用,因为任何后代都可以传递给它。这是一个简单的例子:

procedure PrintToStdOut(Strings: TStrings);
var
  Item: string;
begin
  for Item in Strings do
    Writeln(Item);
end;

显然,当参数声明为TStrings而不是TStringList时,这会有更大的效用。

但是,问题中的代码并不属于这种性质,我相信如果sl被声明为TStringList类型,那么它将会得到如此温和的改进。

答案 2 :(得分:7)

因为这样你可以在TStrings变量中添加另一个SL后代(我可能称之为Strings,而不是SL)。

在您的情况下,这没有实际意义,因为SL周围的逻辑包含TStringList的创建,并且没有外部赋值或参数解析。

但如果您将逻辑从作业中分离出来,那么您可以从使用任何TStrings后代中受益。

例如,TMemoy.LinesTListBox.ItemsTComboBox.Items等 从外面看起来它们是TStrings,但在内部它们不使用TStringList而是使用它们自己的后代。

来自TStrings的类的一些示例:

source\DUnit\Contrib\DUnitWizard\Source\DelphiExperts\Common\XP_OTAEditorUtils.pas:
     TXPEditorStrings = class(TStrings)
source\fmx\FMX.ListBox.pas:
       TListBoxStrings = class(TStrings)
source\fmx\FMX.Memo.pas:
     TMemoLines = class(TStrings)
source\rtl\common\System.Classes.pas:
     TStringList = class(TStrings)
source\vcl\Vcl.ComCtrls.pas:
     TTabStrings = class(TStrings)
     TTreeStrings = class(TStrings)
     TRichEditStrings = class(TStrings)
source\vcl\Vcl.ExtCtrls.pas:
     TPageAccess = class(TStrings)
     THeaderStrings = class(TStrings)
source\vcl\Vcl.Grids.pas:
     TStringGridStrings = class(TStrings)
     TStringSparseList = class(TStrings)
source\vcl\Vcl.Outline.pas:
     TOutlineStrings = class(TStrings)
source\vcl\Vcl.StdCtrls.pas:
     TCustomComboBoxStrings = class(TStrings)
     TMemoStrings = class(TStrings)
     TListBoxStrings = class(TStrings)
source\vcl\Vcl.TabNotBk.pas:
     TTabPageAccess = class(TStrings)

答案 3 :(得分:5)

TStringList是抽象TStrings类的具体实现