Почему переменные объявляются как TStrings и 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 ответов


sl на TStringList и я всегда буду делать это таким образом. Для читателя кода это упрощает понимание списка локальных переменных.

в этом коде 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.


TStrings - абстрактный тип, который не имеет всех реализованных методов.

TStringList является потомком элемента TStrings и выполняет все функции. В вашем коде вы можете объявить свою переменную также как TStringList.

однако, например, в определениях функций имеет смысл принять вместо TStringList:

procedure doSomething(lst: TStrings);

это позволяет функции работать со всеми реализациями TStrings не только TStringList.


потому что таким образом вы могли бы поставить еще один TStrings потомок в SL переменная (я бы, вероятно, назвал это Strings, а не SL).

в вашем случае это спорно, так как логика вокруг SL содержит создание TStringList и никакого внешнего назначения или разбора параметров.

но если вы когда-нибудь разделите логику от задания, то вы можете извлечь выгоду из использования любого TStrings потомок.

например, a TMemoy.Lines, TListBox.Items, TComboBox.Items, etc.
Со стороны кажется, что они 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)

TStringList-это конкретная реализация абстрактного класса TStrings