delphi - crear - ¿Por qué las variables se declaran como TStrings y se crean como TStringList?
crear tstringlist delphi (4)
En mi opinión, eso es bastante inútil, aunque completamente inofensivo. Podrías perfectamente declarar que sl
es TStringList
y siempre lo haría de esa manera. Para un lector del código, hace que la lista de variables locales sea más fácil de comprender.
En este código, a sl
siempre se le asigna una instancia de TStringList
y, por lo tanto, no se gana nada al declarar que sl
tiene el tipo de clase base de TStrings
. Sin embargo, si tiene un código que asigna una variedad de diferentes tipos de descendientes TStrings
a la variable, entonces tendría sentido declararlo como TStrings
.
Las situaciones en las que podría declarar que una variable es de tipo TStrings
normalmente serían cuando el código no estaba creando explícitamente la instancia. Por ejemplo, un método de utilidad que recibió una lista de cadenas como parámetro sería más útil si aceptara una TStrings
ya que cualquier descendente podría TStrings
. Aquí hay un ejemplo simple:
procedure PrintToStdOut(Strings: TStrings);
var
Item: string;
begin
for Item in Strings do
Writeln(Item);
end;
Claramente, esto es de mucha mayor utilidad cuando el parámetro se declara como TStrings
lugar de TStringList
.
Sin embargo, el código en la pregunta no es de esta naturaleza y creo que se mejoraría levemente si se declarase sl
de tipo TStringList
.
¿Por qué las variables se declaran como TStrings
y se crean como TStringList
?
por ejemplo: el var sl
se declara como TStrings
pero se crea como 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;
Porque de esa manera podrías poner otro descendiente TStrings
en la variable SL
(probablemente llamaría a ese Strings
, no a SL
).
En su caso, eso es discutible, ya que la lógica en torno a SL
contiene la creación de una lista de TStringList
de TStringList
y ninguna asignación externa o análisis de parámetros.
Pero si alguna vez separa la lógica de la asignación, entonces podría beneficiarse de usar cualquier descendiente TStrings
.
Por ejemplo, un TMemoy.Lines
, TListBox.Items
, TComboBox.Items
, etc.
Desde fuera, parece que son TStrings
, pero internamente no usan una TStringList
sino su propio descendiente.
Algunos ejemplos de clases que descienden de 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)
una TStringList es una implementación concreta de la clase TStrings abstracta
TStrings
es un tipo abstracto que no tiene todos los métodos implementados.
TStringList
es un descendiente de TStrings
e implementa todas las funciones. En su código, puede declarar su variable también como TStringList
.
Sin embargo, por ejemplo, en las definiciones de funciones, tiene sentido aceptar un parámetro TStrings
lugar de un TStringList
:
procedure doSomething(lst: TStrings);
Esto permite que la función funcione con todas las implementaciones de TStrings
, no solo con TStringList
.