¿Por qué las variables se declaran como TStrings y se crean como TStringList?


¿Por qué las variables se declaran como TStrings y se crean como TStringList?

Eg: el var {[3] } 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;
Author: bluish, 2012-02-21

4 answers

Para mí eso es bastante inútil aunque completamente inofensivo. Podrías perfectamente declarar sl ser TStringList y yo 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 entender.

En este código sl siempre se le asigna una instancia TStringList y por lo tanto no hay nada que ganar al declarar que sl tiene el tipo de clase base de TStrings. Sin embargo, si tuviera un código que asignara una variedad de diferentes tipos de descendientes TStrings a la variable, entonces tendría sentido declararla 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 recibiera una lista de cadenas como parámetro sería más útil si aceptara un TStrings ya que entonces se le podría pasar cualquier descendiente. He aquí un ejemplo sencillo:

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 es declarado TStrings en lugar de TStringList.

Sin Embargo, el código de la pregunta no es de esta naturaleza, y creo que sería muy ligeramente mejorado si sl fue declarada de tipo TStringList.

 28
Author: David Heffernan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 15:01:11

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, podría declarar su variable también como TStringList.

Sin embargo, por ejemplo, en las definiciones de funciones, tiene sentido aceptar un parámetro TStrings en lugar de un TStringList:

procedure doSomething(lst: TStrings);

Esto permite a la función trabajar con todas las implementaciones de TStrings, no solo TStringList.

 31
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 14:57:26

Porque de esa manera podrías poner otro descendiente TStrings en la variable SL (probablemente lo llamaría Strings, no SL).

En su caso, eso es discutible, ya que la lógica alrededor de SL contiene la creación de un TStringList y no hay 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 el exterior se ve como son TStrings, pero internamente no usan un 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)
 7
Author: Jeroen Wiert Pluimers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 21:23:18

Una TStringList es una implementación concreta de la clase abstracta TStrings

 5
Author: Petesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 14:53:06