web-dev-qa-db-fra.com

Pourquoi les variables sont déclarées comme TStrings et créées comme TStringList?

Pourquoi les variables sont déclarées comme TStrings et créées comme TStringList?

par exemple: le var sl est déclaré comme TStrings mais créé comme 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;
39
Fabio Vitale

À mon avis, c'est plutôt inutile, mais complètement inoffensif. Vous pourriez parfaitement déclarer que sl est TStringList et je le ferais toujours de cette façon. Pour un lecteur du code, cela rend la liste des variables locales plus facile à comprendre.

Dans ce code, sl se voit toujours attribuer une instance TStringList et il n'y a donc rien à gagner à déclarer sl pour avoir le type de classe de base TStrings. Cependant, si vous aviez du code qui affectait une variété de différents types de descendants TStrings à la variable, alors il serait logique de la déclarer comme TStrings.

Les situations où vous pouvez déclarer une variable de type TStrings sont généralement lorsque le code ne crée pas explicitement l'instance. Par exemple, une méthode utilitaire qui a reçu une liste de chaînes en tant que paramètre serait plus utile si elle acceptait un TStrings car alors tout descendant pourrait lui être transmis. Voici un exemple simple:

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

Il est clair que cela est beaucoup plus utile lorsque le paramètre est déclaré TStrings plutôt que TStringList.

Cependant, le code dans la question n'est pas de cette nature et je pense qu'il serait toujours si légèrement amélioré si sl était déclaré de type TStringList.

29
David Heffernan

TStrings est un type abstrait qui n'a pas toutes les méthodes implémentées.

TStringList est un descendant de TStrings et implémente toutes les fonctions. Dans votre code, vous pouvez également déclarer votre variable comme TStringList.

Cependant par ex. sur les définitions de fonction, il est logique d'accepter un paramètre TStrings au lieu d'un TStringList:

procedure doSomething(lst: TStrings);

Cela permet à la fonction de fonctionner avec toutes les implémentations de TStrings, pas seulement TStringList.

36
Chris

Parce que de cette façon, vous pourriez mettre un autre descendant TStrings dans la variable SL (je l'appellerais probablement Strings, pas SL).

Dans votre cas, c'est théorique, car la logique autour de SL contient la création d'un TStringList et aucune affectation externe ou analyse de paramètre.

Mais si jamais vous séparez la logique de l'affectation, vous pouvez alors utiliser n'importe quel descendant TStrings.

Par exemple, un TMemoy.Lines, TListBox.Items, TComboBox.Items, etc.
De l'extérieur, il semble qu'ils soient TStrings, mais en interne ils n'utilisent pas un TStringList mais leur propre descendant.

Quelques exemples de classes qui descendent 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)
8
Jeroen Wiert Pluimers

un TStringList est une implémentation concrète de la classe abstraite TStrings

6
Petesh