2010-11-01 21 views
5

Delphi 1 16 Bit (ja es ist alt, aber es funktioniert gut)TStringList - merkwürdiges Verhalten

ein Beispielcode:

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; 

ich das Objektfeld mit Lange Ganz zu speichern (ein Hack Ja, aber es macht den Job erledigt. Wie auch immer, in Zeile A oben würde ich erwarten, dass ShowMessage 100 zeigt, stattdessen zeigt es 999 (auch wenn dupIgnore gesetzt ist). Fehle ich hier etwas? Oder sollte es so funktionieren (ich erwartete, dass die Stringliste die 999 ignoriert)?

Antwort

6

Nur getestet in Delphi 2009 - es zeigt 100 (und es sollte 100 gemäß der Delphi 2009 Dokumentation über Duplikate und dupIgnore zeigen).

Wahrscheinlich ist es Delphi 1 Bug.


Aktualisiert

@Sertac Akyuz: Ja, das wahr zu sein scheint. Google shows, dass alte Delphi-Versionen hatten die folgende Implementierung von TStringList.Add und TStringList.AddObject Methoden:

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; 

Die aktuelle (Delphi 2009) Implementierung ist:

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; 

den Unterschied sehen. Die alte Implementierung kann als Fehler (Speicherleck usw.) oder als nicht dokumentiertes zulässiges Verhalten angesehen werden. In jedem Fall ist die aktuelle Implementierung frei von dem Problem.

+0

[Die Delphi XE-Dokumentation] (http://docwiki.embarcadero.com/VCL/en/Classes.TStringList.AddObject) sagt nichts darüber. Es besagt nur, dass doppelte * Strings * ignoriert werden. Es sagt nichts darüber aus, was mit dem Objekt passiert, das an die doppelte Zeichenfolge gebunden ist. –

+0

@Rob Kennedy - dupIgnore blockiert die Versuche doppelte Strings (mit oder ohne Objekte) zur sortierten Liste hinzuzufügen. Der zurückgegebene Index spielt in diesem Fall keine Rolle - String wird nicht zur Liste hinzugefügt. – kludg

+0

Rob spricht nicht über die Zeichenfolge - es ist sicher nicht hinzugefügt. Er spricht über das * Objekt *, das an die Dupierkette gebunden ist. Die Dokumentation sagt nicht, was mit dem Objekt passiert. Bei früheren Versionen von Delphi ersetzt das Objekt, das mit ihm verknüpft ist, das vorherige Objekt, während die Duplizierungszeichenfolge nicht hinzugefügt wird. Es sollte als eine Designauswahl anstelle eines Fehlers betrachtet werden, wahrscheinlich ein schlechter, seit sie es geändert haben (ich habe einen Beitrag gesehen, der sich mit dem Jahr 2004 beschwert hat, so dass sich das Verhalten wahrscheinlich nach D7 geändert hat). –

3

Sie verpassen nichts. Genau das passiert.

AddObject beginnt mit dem Aufruf Add, die den Index des neuen (oder vorhandenen) Elements in der Liste zurückgibt. Dann ruft es PutObject auf, um den Objektwert an diesem Index zuzuweisen. Verhalten in Bezug auf die Eigenschaft Duplicates ist in der Dokumentation nicht angegeben.

Verwandte Themen