2012-01-20 90 views
11

我想知道這個方法調用做什麼:的TStringList的ADDOBJECT方法

stringList.addObject(String,Object); 

我也想知道這個屬性的作用:

stringList.Objects[i] 

它看起來像鍵,值對同時加入。但是,在循環中檢索什麼被檢索?

我也看到物品[我]打電話。

我對TStringList操作和TList操作感到困惑。

+1

這真是德爾福古代前仿製藥的遺物。現在使用這種粗糙的無類型機制是沒有意義的。通用的「TList 」取代了這種技術。 –

+0

@DavidHeffernan是古老的,但對於無法訪問新版本delphi(> = 2009)的用戶很有用。另外OP沒有指定正在使用的Delphi版本。 – RRUZ

+1

@RRUZ的確如此。使用它之前的泛型,但是一旦你超越了,請停止它。 –

回答

5

AddObject方法允許您存儲與存儲在Item屬性中的字符串關聯的TObject地址(指針)。 Objects屬性用於訪問存儲的對象。

檢查使用AddObject存儲與每個字符串關聯的整數值的簡單採樣。

var 
List : TStringList; 
I : integer; 
begin 
    try 
    List:=TStringList.Create; 
    try 
     List.AddObject('Item 1', TObject(332)); 
     List.AddObject('Item 2', TObject(345)); 
     List.AddObject('Item 3', TObject(644)); 
     List.AddObject('Item 4', TObject(894)); 

     for I := 0 to List.Count-1 do 
     Writeln(Format('The item %d contains the string "%s" and the integer value %d',[I, List[I], Integer(List.Objects[i])])); 
    finally 
     List.Free; 
    end; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 
+1

是的,TStringList.Objects []可以用來存儲值。但請記住,使用XE2指針大小並不總是等於整數大小! –

+1

確實如此,但是如果你使用x64指針是8字節大小,並且完全可以容納一個總是4字節大小的整數。 – RRUZ

+1

如果你在TStringList有一個'OwnsObjects'屬性(和構造函數參數)之前使用delphi,並且你不僅僅是存儲值而是實例引用,那麼你必須釋放你放入這些對象引用的任何實例,然後才能釋放StringList本身(當然,除非這些例子是由其他東西所擁有的)。 –

2

TStringList不僅僅是一個字符串列表。

它可用於名稱值對:

stringlist.Values['apple'] := 'one'; 
stringlist.Values['banana'] := 'two'; 

但它也可用於將字符串與任何對象(或任何指針)關聯。

stringlist.AddObject('apple', TFruit.Create); 
stringlist.AddObject('banana', TFruit.Create); 


i := stringlist.IndexOf('apple'); 
if i >= 0 then 
    myfruit := stringlist.Objects[i] as TFruit; 

TList是存儲指針的列表。它們不與字符串關聯。

+3

-1您*必須在您的回答中提及必須釋放任何分配的對象('TFuit.Create')('for i:= 0 to stringlist.Count-1 do stringList.Objects [i] .Free;'或'OwnsObjects'屬性) - 使用'TStringList'來存儲剛剛創建的對象並不是一個好主意。您可以將它用於擁有VCL管理所有權的對象,或者擁有自己的生命週期。 OP似乎是未經過檢驗的,所以你的回答至少應該提及那個(就像Ken White's一樣)。 –

16

它添加了一對項目:TStringList.Strings列表中的條目和TStringList.Objects列表中的匹配TObject列表。

例如,它允許您存儲提供項目名稱的字符串列表以及包含匹配項目的類別的對象。

type 
    TPerson=class 
    FFirstName, FLastName: string; 
    FDOB: TDateTime; 
    FID: Integer; 
    private 
    function GetDOBAsString: string; 
    function GetFullName: string; 
    published 
    property FirstName: string read FFirstName write FFirstName; 
    property LastName: string read FLastName write FLastName; 
    property DOB: TDateTime read FDOB write FDOB; 
    property DOBString: string read GetDOBAsString; 
    property FullName: string read GetFullName; 
    property ID: Integer read FID write FID; 
    end; 

implementation 

{TPerson} 
function TPerson.GetDOBAsString: string; 
begin 
    Result := 'Unknown'; 
    if FDOB <> 0 then 
    Result := DateToStr(FDOB); 
end; 

function TPerson.GetFullName: string; 
begin 
    Result := FFirstName + ' ' + FLastName; // Or FLastName + ', ' + FFirstName 
end; 

var 
    PersonList: TStringList; 
    Person: TPerson; 
    i: Integer; 
begin 
    PersonList := TStringList.Create; 
    try 
    for i := 0 to 9 do 
    begin 
     Person := TPerson.Create; 
     Person.FirstName := 'John'; 
     Person.LastName := Format('Smith-%d', [i]); // Obviously, 'Smith-1' isn't a common last name. 
     Person.DOB := Date() - RandRange(1500, 3000); // Make up a date of birth 
     Person.ID := i; 
     PersonList.AddObject(Person.LastName, Person); 
    end; 

    // Find 'Smith-06' 
    i := PersonList.IndexOf('Smith-06'); 
    if i > -1 then 
    begin 
     Person := TPerson(PersonList[i]); 
     ShowMessage(Format('Full Name: %s, ID: %d, DOB: %s', 
         [Person.FullName, Person.ID, Person.DOBString])); 
    end; 
    finally 
    for i := 0 to PersonList.Count - 1 do 
     PersonList.Objects[i].Free; 
    PersonList.Free; 
    end; 

這顯然是一個人爲的例子,因爲它不是你真正認爲有用的東西。不過,它展示了這個概念。

另一個方便的用途是存儲一個整數值和一個字符串(例如,顯示TComboBoxTListBox中的項目列表以及用於數據庫查詢的對應ID)。在這種情況下,您只需要在Objects數組中對整數(或其他任何SizeOf(指針))進行類型轉換。

// Assuming LBox is a TListBox on a form: 
while not QryItems.Eof do 
begin 
    LBox.Items.AddObject(QryItem.Fields[0].AsString, TObject(QryItem.Fields[1[.AsInteger)); 
    QryItems.Next; 
end; 

// User makes selection from LBox 
i := LBox.ItemIndex; 
if i > -1 then 
begin 
    ID := Integer(LBox.Items.Objects[i]); 
    QryDetails.ParamByName('ItemID').AsInteger := ID; 
    // Open query and get info. 
end; 

在存儲比實際TObject其他事情的情況下,你並不需要釋放的內容。由於它們不是真實物體,除了TStringList本身以外沒有任何東西可以自由使用。

+2

較新的Delphi版本有一個帶有'OwnsObjects'屬性(和構造函數參數)的TStringList,非常像TObjectList。如果設置爲true,則在釋放列表之前,您不需要(實際上不應該)釋放這些實例。 –

+1

好點,Marjan。謝謝你提到它。 :) –

+0

當例如'stringListB:= stringListA'時描述對象會發生什麼情況會很有幫助。 stringListB.Objects是否將指針的副本帶到原始對象?這是否意味着當我們希望'stringListA'被釋放時,我們不應該一個一個地釋放它所分配的對象? – Vassilis

相關問題