web-dev-qa-db-ja.com

なぜ変数がTStringsとして宣言され、TStringListとして作成されるのですか?

なぜ変数がTStringsとして宣言され、TStringListとして作成されるのですか?

例:変数slTStringsとして宣言されていますが、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

完全に無害であるとはいえ、それはかなり無意味です。あなたは完全にslTStringListであると宣言することができ、私はいつもそのようにします。コードの読者にとっては、ローカル変数のリストが理解しやすくなります。

このコードでは、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と宣言されている場合、これははるかに有用です。

ただし、問題のコードはこの性質のものではなく、slTStringList型であると宣言された場合、コードはこれほど穏やかに改善されると思います。

29
David Heffernan

TStringsは、すべてのメソッドが実装されているわけではない抽象型です。

TStringListTStringsの子孫であり、すべての関数を実装しています。コードでは、変数をTStringListとして宣言することもできます。

しかし、例えば関数定義では、TStringsの代わりにTStringListパラメータを受け入れることは理にかなっています:

procedure doSomething(lst: TStrings);

これにより、関数はTStringsだけでなく、TStringListのすべての実装で機能するようになります。

36
Chris

そのようにして、別のTStringsの子孫をSL変数に入れることができます(おそらくStringsではなくSLと呼びます)。

あなたの場合、SLの周りのロジックにはTStringListの作成が含まれており、外部割り当てやパラメーター解析は含まれていないため、それは意味がありません。

ただし、ロジックを割り当てから分離した場合は、TStringsの子孫を使用することでメリットが得られます。

たとえば、TMemoy.LinesTListBox.ItemsTComboBox.Itemsなど.
外から見ると、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)

tStringListは、抽象TStringsクラスの具象実装です

6
Petesh