2012-02-21 99 views
34

爲什麼變量聲明爲TStrings並創建爲TStringList爲什麼變量被聲明爲TStrings並創建爲TStringList?

例如:The VAR sl聲明爲TStrings但創建爲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; 
+9

我的最重要的原因:字符串列表包括少打字:) – mjn 2012-02-21 15:50:26

+2

@mjn爲什麼不走一路,並添加'TSL = TStringList'到一個包含文件你包括在每個單位....... ;-) – 2012-02-21 16:06:35

+1

非常好的問題!我相信這個問題的根源在於通常使用變量的根祖先類型的VCL源代碼,比如'TControl'。編碼器(包括我)傾向於根據每個變量,但它沒有意義。感謝您讓我考慮一下。 – NGLN 2012-02-21 18:06:55

回答

28

在我看來的具體實現,是毫無意義雖然是完全無害的。你可以很好地宣佈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

但是,問題中的代碼不屬於這種性質,我相信如果sl被聲明爲TStringList類型,它將會如此溫和地得到改進。

+11

正如你所指出的(但沒有太好描述),這是一個好設計的原因是它允許你在'PrintToStdOut'中使用任何'TStrings'後代,所以'TStringList','Memo1.Lines','ListBox1 .Items'等工作得很好。聲明它採用'TStringList'意味着最後兩次調用會失敗。 – 2012-02-21 17:23:42

+0

嗯,**我**是錯的。 – OnTheFly 2012-02-22 15:16:05

5

一個的TStringList是抽象的字符串列表類

+0

這是真的,但它不回答這個問題。 – jpfollenius 2012-02-21 18:38:47

+3

這種類型的確如此,如果你知道爲什麼有抽象基類是好的,那麼有時候有一個接口也是一個好主意。在delphi中,抽象基類是沒有引用計數的單繼承接口。 – 2012-02-22 02:58:37

31

TStrings是一個沒有實現所有方法的抽象類型。

TStringListTStrings的後代並實現所有功能。在你的代碼中,你可以聲明你的變量爲TStringList

然而,例如,在函數定義是有意義的接受TStrings參數而不是TStringList

procedure doSomething(lst: TStrings); 

這使得與TStrings所有實現,不僅TStringList工作的功能。

+3

+1好的答案 - 簡潔! – Argalatyr 2012-02-22 06:37:16

+0

直接,很簡單:謝謝! – jcfaria 2017-10-28 14:12:47

7

因爲這樣你可以把另一個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) 
+1

+ 1,很好的研究。 – PresleyDias 2012-02-22 08:12:37

相關問題