Why variables are declared as TStrings and created as TStringList?

后端 未结 4 946
故里飘歌
故里飘歌 2021-02-06 21:46

Why variables are declared as TStrings and created as TStringList?

eg: the var sl is declared as TStrings but created

相关标签:
4条回答
  • 2021-02-06 22:01

    Because that way you could put another TStrings descendant in the SL variable (I'd probably call that Strings, not SL).

    In your case, that is moot, since the logic around SL contains the creation of a TStringList and no external assignment or parameter parsing.

    But if you ever split the logic away from the assignment, then you could benefit from using any TStrings descendant.

    For instance, a TMemoy.Lines, TListBox.Items, TComboBox.Items, etc.
    From the outside it looks like they are TStrings, but internally they do not use a TStringList but their own descendant.

    A few examples of classes that descend from 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)
    
    0 讨论(0)
  • 2021-02-06 22:03

    TStrings is an abstract type that doesn't have all methods implemented.

    TStringList is a descendant of TStrings and implements all functions. In your code, you could declare your variable also as TStringList.

    However e.g. on function definitions it makes sense to accept a TStrings parameter instead of a TStringList:

    procedure doSomething(lst: TStrings);
    

    This enables the function to work with all implementations of TStrings, not only TStringList.

    0 讨论(0)
  • 2021-02-06 22:11

    a TStringList is a concrete implementation of the abstract TStrings class

    0 讨论(0)
  • 2021-02-06 22:16

    To my mind that is rather pointless albeit completely harmless. You could perfectly well declare sl to be TStringList and I would always do it that way. For a reader of the code it makes the list of local variables easier to understand.

    In this code sl is always assigned a TStringList instance and so there's nothing to be gained from declaring sl to have the base class type of TStrings. However, if you had code that assigned a variety of different types of TStrings descendants to the variable, then it would make sense to declare it as TStrings.

    The situations when you might declare a variable to be of type TStrings would typically be when the code was not explicitly creating the instance. For example a utility method that received a string list as a parameter would be more useful if it accepted a TStrings since then any descendant could be passed to it. Here's a simple example:

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

    Clearly this is of much greater utility when the parameter is declared to be TStrings rather than TStringList.

    However, the code in the question is not of this nature and I believe that it would be ever so mildly improved if sl was declared to be of type TStringList.

    0 讨论(0)
提交回复
热议问题