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