42

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

例如:varsl被声明为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

4 回答 4

41

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

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

TStrings然而,例如在函数定义中,接受参数而不是 a是有意义的TStringList

procedure doSomething(lst: TStrings);

这使该函数能够与 的所有实现一起工作TStrings,而不仅仅是TStringList.

于 2012-02-21T14:57:26.497 回答
33

在我看来,尽管完全无害,但这是毫无意义的。你完全可以宣称slTStringList,我会一直那样做。对于代码的读者来说,它使局部变量列表更容易理解。

在这段代码sl中,总是分配一个TStringList实例,因此声明sl基类类型为TStrings. 但是,如果您的代码为变量分配了各种不同类型的TStrings后代,那么将其声明为TStrings.

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

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

显然,当参数被声明为TStrings而不是TStringList.

sl但是,问题中的代码不属于这种性质,我相信如果声明为 type ,它会得到如此温和的改进TStringList

于 2012-02-21T14:54:23.510 回答
10

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

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

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

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

来自 的类的一些示例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)
于 2012-02-21T21:23:18.297 回答
7

TStringList 是抽象 TStrings 类的具体实现

于 2012-02-21T14:53:06.680 回答