2010-11-01 103 views
5

Delphi 1中的16位(是它的老,但它工作得很好)的TStringList - 古怪的行爲

一些示例代碼:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    SL: TStringList; 
begin 

    SL := TStringList.Create; 
    SL.Sorted := True; 
    SL.Duplicates := dupIgnore; 

    SL.AddObject('A', TObject(100)); 
    SL.AddObject('A', TObject(999)); 
    ShowMessage(IntToStr(LongInt(SL.Objects[0]))); {A} 

    SL.Free; 

end; 

我使用的對象字段存儲longints(一劈,是的,但它完成了工作)。無論如何,在上面的A行我希望ShowMessage顯示100,而不是顯示999(即使dupIgnore設置)。我在這裏錯過了什麼嗎?或者它應該以這種方式工作(我希望stringlist忽略999)?

回答

6

剛剛在德爾福2009年測試 - 它顯示100(根據德爾福2009年關於重複和dupIgnore文檔它應該顯示100)。

可能是Delphi 1的一個bug。


更新

@Sertac Akyuz:是的,這似乎是真實的。 Google shows老德爾福版本有以下實現的TStringList.Add和TStringList.AddObject方法:

function TStringList.Add(const S: string): integer; 
begin 
    if not Sorted then 
    Result := FCount 
    else 
    if Find(S, Result) then 
     case Duplicates of 
     dupIgnore: Exit; 
     dupError: Error(SDuplicateString, 0); 
     end; 
    InsertItem(Result, S); 
end; 

function TStrings.AddObject(const S: string; AObject: TObject): Integer; 
begin 
    Result := Add(S); 
    PutObject(Result, AObject); 
end; 

目前(2009年德爾福)的實現是:

function TStringList.Add(const S: string): Integer; 
begin 
    Result := AddObject(S, nil); 
end; 

function TStringList.AddObject(const S: string; AObject: TObject): Integer; 
begin 
    if not Sorted then 
    Result := FCount 
    else 
    if Find(S, Result) then 
     case Duplicates of 
     dupIgnore: Exit; 
     dupError: Error(@SDuplicateString, 0); 
     end; 
    InsertItem(Result, S, AObject); 
end; 

看到區別。舊的實現可能被視爲一個錯誤(內存泄漏等)或一個未公開的允許的行爲。無論如何,目前的實施都沒有問題。

+0

[Delphi XE文檔](http://docwiki.embarcadero.com/VCL/en/Classes.TStringList.AddObject)沒有提到它。它只是說重複*字符串*被忽略。它沒有說明綁定到重複字符串的對象會發生什麼。 – 2010-11-01 17:15:49

+0

@Rob Kennedy - dupIgnore阻止嘗試添加重複的字符串(帶或不帶對象)到排序列表。返回的索引在這種情況下無關緊要 - 字符串不會添加到列表中。 – kludg 2010-11-01 17:35:19

+0

羅布不是在談論這個字符串 - 它肯定不會被添加。他談論了綁在絃樂器上的*物體*。文檔沒有說明對象發生了什麼。在早期版本的Delphi中,雖然不添加重複字符串,但綁定到它的對象會替換先前的對象。它應該被認爲是一個設計選擇,而不是一個bug,可能是一個錯誤,因爲他們改變了它(我見過一個投訴日期爲2004年,所以行爲可能在D7之後改變)。 – 2010-11-01 23:22:01

3

你不會錯過任何東西。這正是發生的情況。

AddObject首先調用Add,它返回列表中新(或現有)元素的索引。然後它調用PutObject在該索引處分配對象值。在文檔中未指定相對於Duplicates屬性的行爲。